1)標記非活動對象
--何為非活動對象,通俗的講,就是無引用的對象。
追蹤root對象算法: 深度追蹤root對象,將heap中所有被引用到的root做標志,所有未被標志的對象視為非活動對象,所占用的空間視為非活動內(nèi)存。
2)清理非活動對象
Copy算法:
方法:將內(nèi)存分為兩個區(qū)域(from space和to space)。所有的對象分配內(nèi)存都分配到from space。在清理非活動對象階段,把所有標志為活動的對象,copy到to space,之后清楚from space空間。然后互換from sapce和to space的身份。既原先的from space變成to sapce,原先的to space變成from space。每次清理,重復上述過程。
優(yōu)點:copy算法不理會非活動對象,copy數(shù)量僅僅取決為活動對象的數(shù)量。并且在copy的同時,整理了heap空間,即,to space的空間使用始終是連續(xù)的,內(nèi)存使用效率得到提高。
缺點:劃分from space和to space,內(nèi)存的使用率是1/2。
Compaction算法:
方法:在清理非活動對象階段,刪除非活動對象占用內(nèi)存,并且把活動對象向heap的底部移動,直到所有的活動對象被移到heap的一側(cè)。
優(yōu)點:無須劃分from sapce和to space,提高內(nèi)存的使用率。并且compaction后的內(nèi)存空間也是連續(xù)分配的。
缺點:該算法相對比較復雜。
sun jdk gc介紹:
在減少gc之前,先來看看來自IBM的一組統(tǒng)計數(shù)據(jù):
98%的java對象,在創(chuàng)建之后不久就變成了非活動對象;只有2%的對象,會在長時間一直處于活動狀態(tài)。
如果能對這兩種對象區(qū)分對象,那么會提交GC的效率。在sun jdk gc中(具體的說,是在jdk1.4之后的版本),提出了不同生命周期的GC策略。
young generation:
生命周期很短的對象,歸為young generation。由于生命周期很短,這部分對象在gc的時候,很大部分的對象已經(jīng)成為非活動對象。因此針對young generation的對象,采用copy算法,只需要將少量的存活下來的對象copy到to space。存活的對象數(shù)量越少,那么copy算法的效率越高。
young generation的gc稱為minor gc。經(jīng)過數(shù)次minor gc,依舊存活的對象,將被移出young generation,移到tenured generation(下面將會介紹)
young generation分為:
eden:每當對象創(chuàng)建的時候,總是被分配在這個區(qū)域
survivor1:copy算法中的from space
survivor2:copy算法中的to sapce (備注:其中survivor1和survivor2的身份在每次minor gc后被互換)
minor gc的時候,會把eden+survivor1(2)的對象copy到survivor2(1)去。
tenured generation:
生命周期較常的對象,歸入到tenured generation。一般是經(jīng)過多次minor gc,還 依舊存活的對象,將移入到tenured generation。(當然,在minor gc中如果存活的對象的超過survivor的容量,放不下的對象會直接移入到tenured generation)
tenured generation的gc稱為major gc,就是通常說的full gc。
采用compactiion算法。由于tenured generaion區(qū)域比較大,而且通常對象生命周期都比較常,compaction需要一定時間。所以這部分的gc時間比較長。
minor gc可能引發(fā)full gc。當eden+from space的空間大于tenured generation區(qū)的剩余空間時,會引發(fā)full gc。這是悲觀算法,要確保eden+from space的對象如果都存活,必須有足夠的tenured generation空間存放這些對象。
Permanet Generation:
該區(qū)域比較穩(wěn)定,主要用于存放classloader信息,比如類信息和method信息。
對于spring hibernate這些需要動態(tài)類型支持的框架,這個區(qū)域需要足夠的空間。
這部分內(nèi)容相對比較理論,可以結(jié)合jstat,jmap等命令(當然也可以使用jconsole,jprofile,gciewer等工具),觀察jdk gc的情況。
來自:http://www.blogjava.net/stone2083/archive/2008/03/15/186507.html