Java GC 簡要分析

一:java GC原理

    java虛擬機啓動之初,內存分配如下圖所示,由分爲三個部分young新生代、Tenrued永久生代和perm組成。新生代主要是生成對象,永久生代是用來保存那些程序運行過程一直被引用的一些對象,permanent generation是用來保存一些特殊對象,比如類和方法存儲的地方等等。 
  運行過程中大多數的對象是有young generation(新生代)來生成,並且大多對象也在哪裏死亡然後被垃圾回收。young新生代又分爲 eden 和兩個survivor spaces。大部分的對象是eden來生成。兩個survivor spaces其中的一個倖存空間永遠是空的,用來保存垃圾收集後倖存對象和另一個倖存空間的對象。 當新生代滿了以後 minor collection就啓動,收集對象進行垃圾回收,此時會有一些倖存下來的對象(仍舊被引用)這些對象會被轉移到tenured generation(持久生代)。 但是當tenured generation也滿了的時候,就會觸發major collection此時整個heap內的對象都會被收集然後進行垃圾回收(即full gc)。圖中還有一些標誌爲Virtual地方,實際是指 內存在運行中對象佔用內存不多,有些空間還沒有被實際分配物理地址,但是隨着對象佔用的空間越來越大時,這些Virtual空間隨時就會被佔用。這跟啓動java虛擬機時分配的最小地址有關,比如 啓動時 -xms 爲600M  而-xmx 爲2048M則剛開始只有600M的空間是分配了,剩下的還有很多是虛擬空間等待被使用。

space usage by generations

       

二:gc日誌分析
1.當啓動時增加 -verbose:gc 參數後gc日誌會如下所示
[GC 325407K->83000K(776768K), 0.2300771 secs]
[GC 325816K->83372K(776768K), 0.2454258 secs]
[Full GC 267628K->83769K(776768K), 1.8479984 secs]
如上所示,包含了兩次minor collection 和一次major collection,例如325407K和83000K是指經過一次minor垃圾收集後所有活着對象所佔的空間,這些對象包括所以在永久生代或者被永久生代引用或者被permanent 引用的對象,即內存中所有的活着的對象。而括號中的數是指所有被物理分配空間的大小,即除去virtual大小的空間,官方文檔稱爲committed space。後面的時間是垃圾回收耗費的時間。下面的Full Gc也是類似。

2.如果啓動時增加 -XX:+PrintGCDetails 這個參數則gc日誌如下所示
  [GC [PSYoungGen: 671728K->4848K(674304K)] 747836K->84256K(2039680K), 0.0230930 secs] 
 PSYoungGen 是垃圾收集器的類型,671728K->4848K,是新生代在垃圾回收前後的內存佔用,(674304K)是新生代committed的內存大小。747836K->84256K(2039680K)是Heap總量回收前後內存使用情況,(2039680K)是Heap總量commit值佔用情況,0.0230930 secs是gc耗費時間。

即:

[GC [<collector>: <starting occupancy1> -> <ending occupancy1>, <pause time1> secs] <starting occupancy3> -> <ending occupancy3>, <pause time3> secs]

<collector>                     GC收集器的名稱
<starting occupancy1>    	新生代在GC前佔用的內存
<ending occupancy1>     	新生代在GC後佔用的內存
<pause time1>                 	新生代局部收集時jvm暫停處理的時間
<starting occupancy3>    	JVM Heap 在GC前佔用的內存
<ending occupancy3>     	JVM Heap 在GC後佔用的內存
 <pause time3>                	GC過程中jvm暫停處理的總時間


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章