JVM:垃圾回收問題

在什麼時候觸發垃圾回收

由於對象進行了分代處理,因此垃圾回收區域、時間也不一樣。GC有兩種類型:minor GC 和Full GC。

minor GC

一般情況下,當新對象生成,並且在Eden申請空間失敗時,就會觸發minor GC ,對Eden區域進行GC,清除非存活對象,並且把尚且存活的對象移動到Survivor區。然後整理Survivor的兩個區。這種方式的GC是對年輕代的Eden區進行,不會影響到年老代。因爲大部分對象都是從Eden區開始的,同時Eden區不會分配的很大,所以Eden區的GC會頻繁進行。因而,一般在這裏需要使用速度快、效率高的算法,使Eden去能儘快空閒出來。

對整個堆進行整理,包括Young、Tenured和Perm。Full GC因爲需要對整個塊進行回收,所以比Scavenge GC要慢,因此應該儘可能減少Full GC的次數。在對JVM調優的過程中,很大一部分工作就是對於FullGC的調節。有如下原因可能導致Full GC:

finalize()方法

(1)每個對象只能調用finalize( )方法一次。如果在finalize( )方法執行時產生異常(exception),則該對象仍可以被垃圾收集器收集。

(2)垃圾收集器跟蹤每一個對象,收集那些不可觸及的對象(即該對象不再被程序引用 了),回收其佔有的內存空間。但在進行垃圾收集的時候,垃圾收集器會調用該對象的finalize( )方法(如果有)。如果在finalize()方法中,又使得該對象被程序引用(俗稱復活了),則該對象就變成了可觸及的對象,暫時不會被垃圾收集了。但是由於每個對象只能調用一次finalize( )方法,所以每個對象也只可能 “復活 “一次。

(3)Java語言允許程序員爲任何方法添加finalize( )方法,該方法會在垃圾收集器交換回收對象之前被調用。但不要過分依賴該方法對系統資源進行回收和再利用,因爲該方法調用後的執行結果是不可預知的。

(4)垃圾收集器不可以被強制執行,但程序員可以通過調研System.gc方法來建議執行垃圾收集。記住,只是建議。一般不建議自己寫System.gc,因爲會加大垃圾收集工作量。

哪些需要回收

主要根據可達性分析算法,如果一個對象不可達,那麼就是可以回收的;如果一個對象可達,那麼這個對象就不可以回收。對於可達性分析算法,它是通過一系列稱爲“GC Roots” 的對象作爲起始點,當一個對象到 GC Roots 沒有任何引用鏈相接的時候,那麼這個對象就是不可達,就可以被回收。

這個GC Root 對象可以是一些靜態的對象,Java方法的local變量或參數, native 方法引用的對象,活着的線程。

回收過程
主要做了清理對象,整理內存的工作。Java堆分爲新生代和老年代,採用了不同的回收方式。例如新生代採用了複製算法老年代採用了標記整理法。在新生代中,分爲一個Eden 區域和兩個Survivor區域,真正使用的是一個Eden區域和一個Survivor區域,GC的時候,會把存活的對象放入到另外一個Survivor區域中,然後再把這個Eden區域和Survivor區域清除。那麼對於老年代,採用的是標記整理法,首先標記出存活的對象,然後再移動到一端。這樣也有利於減少內存碎片。

GC日誌

5.617(時間戳): [GC(Young GC) 5.617(時間戳): [ParNew(使用ParNew作爲年輕代的垃圾回收期): 43296K(年輕代垃圾回收前的大小)->7006K(年輕代垃圾回收以後的大小)(47808K)(年輕代的總大小), 0.0136826 secs(回收時間)] 44992K(堆區垃圾回收前的大小)->8702K(堆區垃圾回收後的大小)(252608K)(堆區總大小), 0.0137904 secs(回收時間)] [Times: user=0.03(Young GC用戶耗時) sys=0.00(Young GC系統耗時), real=0.02 secs(Young GC實際耗時)]  

總結:

1、主要回收場所:JVM方法區,JVM方法棧。
2、回收方式: 新生代(複製算法),老年代(標記整理法)。
3、根據Young / Old 判斷是新生代還是老年代的 GC,然後就是給出 Young / Old ,整個堆內存 GC 前後的大小。 

參考:
JVM分代垃圾回收策略的基礎概念
http://www.cnblogs.com/laoyangHJ/archive/2011/08/17/JVM.html
深入理解JVM–JVM垃圾回收機制
http://jbutton.iteye.com/blog/1569746

http://icyfenix.iteye.com/blog/715301

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