天天看點

Minor GC、Major GC與Full GC

先簡單介紹一下:

Minor GC:從年輕代空間(包括 Eden 和 Survivor 區域)回收記憶體被稱為 Minor GC。

Major GC:是清理老年代。

Full GC:是清理整個堆空間—包括年輕代和老年代。

Minor GC、Major GC與Full GC

年輕代是大多數新對象建立和銷毀的地方,對象從Young generation區域消失的過程我們稱之為”minor GC“ 當年輕代滿時,會引發“minor GC”。

新生代分為三個空間:

Eden、Survivor from、Survivor to

為什麼要把新生代分為三個區呢,接下來就解釋原因:

1.将任何新對象配置設定給eden空間。 兩個survivor空間開始為空。

Minor GC、Major GC與Full GC

2.當Eden滿的時候,Minor GC 被觸發

Minor GC、Major GC與Full GC

3.被引用的對象被移動到第一個survivor空間。 當eden空間被清除時,未被引用的對象被删除

Minor GC、Major GC與Full GC

4.在下一個次要的GC中,同樣的事情發生在eden空間。 未引用的對象被删除,引用的對象被移動到survivor空間。 然而,在這種情況下,它們被移動到第二幸存者空間(S1)。 另外,來自第一survivor空間(S0)的最後一個Minor GC的對象的年齡增加并被移動到S1。 一旦所有幸存的物體都移動到S1,S0和eden都被清除。 請注意,我們現在在幸存者空間中有不同的老化對象。

Minor GC、Major GC與Full GC

5.在下一個次minor GC中,重複相同的過程。 但這次survivor空間轉換。 被引用的對象被移動到S0。 幸存的對象逐漸老化。 Eden和S1被清除。

Minor GC、Major GC與Full GC

6.當這種minor GC過程不斷進行,當年齡達到一定年齡的門檻(這裡假設是8 )時,他們從年輕代到老年代。(這裡說一下:虛拟機給每個對象定義了一個對象年齡(Age)計數器。如果對象在 Eden 出生并經過第一次 Minor GC 後仍然存活,并且能被 Survivor 容納的話,将被移動到 Survivor 空間中,并将對象年齡設為 1。對象在 Survivor 區中每熬過一次 Minor GC,年齡就增加 1 歲,當它的年齡增加到一定程度(預設為 15 歲)時,就會被晉升到老年代中。對象晉升老年代的年齡門檻值,可以通過參數 -XX:MaxTenuringThreshold (門檻值)來設定。)

Minor GC、Major GC與Full GC

7.随着minor GC的繼續發生,對象将繼續被推廣到老一代的空間。

Minor GC、Major GC與Full GC

8.是以這幾乎涵蓋了與年輕一代的整個過程。 最終,一個Major GC将在老一代進行,清理和壓縮這個空間。

Minor GC、Major GC與Full 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

繼續閱讀