通常來(lái)說,要寫Java代碼,你基本上都沒必要聽說垃圾回收這個(gè)概念的。這不,對(duì)于已經(jīng)寫了多年Java代碼的我來(lái)說,我還沒有哪次經(jīng)歷說是需要使用垃圾回收方面的知識(shí)來(lái)解決問題的。但是,我依然督促自己花了幾天時(shí)間系統(tǒng)性地(也比較淺顯地)學(xué)習(xí)了Java垃圾回收機(jī)制。我認(rèn)為學(xué)習(xí)Java垃圾回收機(jī)制至少可以得到以下幾方面的好處:
對(duì)于系統(tǒng)調(diào)優(yōu)有直接幫助
增加和同行聊天或者下一份工作面試時(shí)的談資
在追求技術(shù)卓越上更進(jìn)一步
(一)Java堆內(nèi)存的分代管理
Java垃圾回收是需要消耗CPU和內(nèi)存資源的,其速度隨著內(nèi)存的變大而減慢,這將嚴(yán)重影響系統(tǒng)的性能。同時(shí),Java系統(tǒng)中存在著這么一種現(xiàn)象:大多數(shù)Java對(duì)象都是“短命”的?;诖耍琂ava采用了分代的內(nèi)存管理方式,并在不同的內(nèi)存代中采用不同的垃圾回收算法,從而達(dá)到對(duì)內(nèi)存更細(xì)粒度的管理,最大限度地減小垃圾回收對(duì)系統(tǒng)本身的影響。
由上圖所示,Java的堆空間被分為了三個(gè)區(qū)域,分別是新生代(Young Generation)、老年代(Old Generation)和永久代(Permanent Generation)。新創(chuàng)建出來(lái)的對(duì)象首先存放在新生代,經(jīng)過新生代中多次垃圾回收(在Survivor 0和Survivor 1之間來(lái)回復(fù)制),存活下來(lái)的對(duì)象將被轉(zhuǎn)移到老年代。新生代中垃圾回收很頻繁,這樣多數(shù)“短命”的對(duì)象將得到及時(shí)清理;又由于新生代內(nèi)存空間通常不大,回收速度也相對(duì)較快。在老年代中,存放著從新生代中經(jīng)歷了多次垃圾回收后仍然存活的對(duì)象,這些對(duì)象相對(duì)較少,而老年代內(nèi)存一般很大,并不容易塞滿,因此老年代的垃圾回收頻率要遠(yuǎn)遠(yuǎn)低于新生代,從而減少了對(duì)系統(tǒng)性能的影響。永久代中主要存放Java類本身的數(shù)據(jù)信息,當(dāng)Java類不再被使用時(shí),也會(huì)被垃圾回收掉。開發(fā)者們通常無(wú)法預(yù)測(cè)永久代的大小,導(dǎo)致程序經(jīng)常出現(xiàn) “java.lang.OutOfMemoryError: Permgen s