Minor GC、Major GC與Full GC

先簡單介紹一下:
Minor GC:從年輕代空間(包括 Eden 和 Survivor 區域)回收內存被稱爲 Minor GC。
Major GC:是清理老年代。
Full GC:是清理整個堆空間—包括年輕代和老年代。
這裏寫圖片描述
年輕代是大多數新對象創建和銷燬的地方,對象從Young generation區域消失的過程我們稱之爲”minor GC“ 當年輕代滿時,會引發“minor GC”。
新生代分爲三個空間:
Eden、Survivor from、Survivor to
爲什麼要把新生代分爲三個區呢,接下來就解釋原因:
1.將任何新對象分配給eden空間。 兩個survivor空間開始爲空。
這裏寫圖片描述
2.當Eden滿的時候,Minor GC 被觸發
這裏寫圖片描述
3.被引用的對象被移動到第一個survivor空間。 當eden空間被清除時,未被引用的對象被刪除
這裏寫圖片描述
4.在下一個次要的GC中,同樣的事情發生在eden空間。 未引用的對象被刪除,引用的對象被移動到survivor空間。 然而,在這種情況下,它們被移動到第二倖存者空間(S1)。 另外,來自第一survivor空間(S0)的最後一個Minor GC的對象的年齡增加並被移動到S1。 一旦所有幸存的物體都移動到S1,S0和eden都被清除。 請注意,我們現在在倖存者空間中有不同的老化對象。
這裏寫圖片描述
5.在下一個次minor GC中,重複相同的過程。 但這次survivor空間轉換。 被引用的對象被移動到S0。 倖存的對象逐漸老化。 Eden和S1被清除。
這裏寫圖片描述
6.當這種minor GC過程不斷進行,當年齡達到一定年齡的門檻(這裏假設是8 )時,他們從年輕代到老年代。(這裏說一下:虛擬機給每個對象定義了一個對象年齡(Age)計數器。如果對象在 Eden 出生並經過第一次 Minor GC 後仍然存活,並且能被 Survivor 容納的話,將被移動到 Survivor 空間中,並將對象年齡設爲 1。對象在 Survivor 區中每熬過一次 Minor GC,年齡就增加 1 歲,當它的年齡增加到一定程度(默認爲 15 歲)時,就會被晉升到老年代中。對象晉升老年代的年齡閾值,可以通過參數 -XX:MaxTenuringThreshold (閾值)來設置。)

這裏寫圖片描述
7.隨着minor GC的繼續發生,對象將繼續被推廣到老一代的空間。
這裏寫圖片描述
8.所以這幾乎涵蓋了與年輕一代的整個過程。 最終,一個Major GC將在老一代進行,清理和壓縮這個空間。
這裏寫圖片描述
寫到這裏,相信讀者對Minor GC的全過程應該很瞭解了。
在這裏提一個術語:Stop the World Event
截取官網一段原話:
Stop the World Event - All minor garbage collections are “Stop the World” events. This means that all application threads are stopped until the operation completes. Minor garbage collections are always Stop the World events.Major garbage collection are also Stop the World events. Often a major collection is much slower because it involves all live objects. So for Responsive applications, major garbage collections should be minimized. Also note, that the length of the Stop the World event for a major garbage collection is affected by the kind of garbage collector that is used for the old generation space.
所有的minor GC都是“stop the world”,這意味着 JVM 因爲要執行GC而停止了應用程序的執行。當Stop-the-world發生時,除了GC所需的線程以外,所有線程都處於等待狀態,直到GC任務完成。GC優化很多時候就是指減少Stop-the-world發生的時間。
MinGC\MajorGC都屬於Stop-the-world, 那爲什麼MajorGC耗時較長呢?因爲OldGen包含了大量倖存下來的對象。
下面說說MinorGC 和 FullGC
簡單的講:
Major GC 是清理OldGen。
Full GC 是清理整個堆空間—包括年輕代和永久代。
很不幸,實際上它還有點複雜且令人困惑。首先,許多 Major GC 是由 Minor GC 觸發的,所以很多情況下將這兩種 GC 分離是不太可能的。另一方面,許多現代垃圾收集機制會清理部分永久代空間,所以使用“cleaning”一詞只是部分正確。
這使得我們不用去關心到底是叫 Major GC 還是 Full GC,大家應該關注當前的 GC 是否停止了所有應用程序的線程,還是能夠併發的處理而不用停掉應用程序的線程。
通常當老年代滿的時候會觸發full GC,但可能還有其他情況。
老年代的垃圾回收策略:
老年代空間的GC事件基本上是在空間已滿時發生,執行的過程根據GC類型不同而不同
JDK7一共有5種GC類型:
Serial GC
Parallel GC
Parallel Old GC (Parallel Compacting GC)
Concurrent Mark & Sweep GC (or “CMS”)
Garbage First (G1) GC
具體如何實現,我的另外一篇博文:http://blog.csdn.net/sky_100/article/details/70791886有介紹,感興趣可以去看看。
說到這,不知道讀者會不會想到一個問題,當發生一次Minor GC的時候,發現survivor區滿了,怎麼辦?在這裏,就引出了另一個問題,什麼對象會進入老年代?經過查閱資料,發現出現這幾種情況,對象會進入老年代:
1.當然是上面講了當對象年齡到達臨界值時,該臨界值由參數:-XX:MaxTenuringThreshold來設置。
2.大對象直接進入老年代中。-XX:+PretenuerSizeThreshold 控制”大對象的“的大小。即當創建的對象大於這個臨界值時,則該對象直接進入老年代。
3.動態對象年齡判定:虛擬機並不總是要求對象的年齡必須達到MaxTenuringThreshold才能晉升到老年代,如果在Survivor區中相同年齡(設年齡爲age)的對象的所有大小之和超過Survivor空間的一半,年齡大於或等於該年齡(age)的對象就可以直接進入老年代,無需等到MaxTenuringThreshold中要求的年齡。
4.解決剛提出的問題,如果出現大量對象在minor gc後仍然存活的情況時,就需要老年代進行分配擔保,讓survivor無法容納的對象直接進入老年代。
參考文章:
http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

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