jvm學習筆記(3)——java對象的內存分配和對象的回收(GC)

引言:    

    之前的文章已經提過,java對象實例是存放在堆上的,至於是在伊甸區、存活區還是老年區,這些都是從對象回收(GC)角度來進行的邏輯劃分。所以我們先說對象的回收(GC),然後再依據GC的策略來說明新的對象具體在哪個區生成。

 

GC(Garbage Collection):

    垃圾回收,指的就是jvm佔用內存的回收。那麼需要回答3個問題:

  • 哪些內存需要回收?——>可達性分析算法。
  • 什麼時候回收?——>簡單的來說,伊甸區的空間不足發生新生代GC(Minor GC),老年代空間不足的時候發生老年代GC(Major GC / Full GC)
  • 如何回收?——>通過垃圾回收器,jdk8默認的是UseParallelGC(PS scavenge + Serial Old),還有UseConMarkSweepGC(ParNew + CMS + Serial Old),以及UseG1GC(G1)。

 

1、可達性分析算法:以一系列成爲“GC Root”的對象最爲起始點,當一個對象沒有到達GC Roots的引用鏈條,就判定這個對象爲可回收的。

    GC Roots對象:

  • 虛擬機棧(棧幀中的本地變量表)中引用的對象。
  • 方法區中類靜態屬性引用的對象。
  • 方法區中常量引用的對象。
  • 本地方法棧中JNI(即Native方法)引用的對象。

2、垃圾收集算法(分代收集):

  • 新生代,對象存活率較低,複製算法。
  • 老年代,對象存活率較高,標記-整理算法、標記-清除算法。

3、垃圾收集器:

新生代收集器:

  • Serial收集器:採用“複製”算法,暫停用戶線程,單線程收集。
  • ParNew收集器:採用“複製”算法,暫停所有用戶線程,採用多線程並行收集。和CMS老年代收集器搭配使用。關注點:GC時用戶線程的停頓時間。
  • Parallel Scavenge收集器:採用“複製”算法,和ParNew收集器類似,但關注點不同。關注點:高吞吐量。

老年代收集器:

  • Serial Old 收集器:採用“標記-整理”算法,暫停用戶線程,單線程收集。和Parallel Scavenge收集器搭配使用。
  • Parallel Old收集器:採用“標記-整理”算法,暫停用戶線程,多線程並行收集。和Parallel Scavenge收集器搭配使用。
  • CMS(Concurrent Mark Sweep)收集器:採用“標記-清除”算法,不暫停用戶線程,多線程併發收集。與ParNew收集器搭配使用。

新一代收集器:

    G1(Garbage-First)收集器:

  • GC工作時爲並行,GC與用戶線程爲併發;
  • 可獨立管理整個GC堆,不需要與其他GC收集器配合使用;
  • 空間整合:整理上看是“標記-整理”算法實現的,從局部(兩個Region之間)上看是基於“複製”算法實現的。

總結:

  1. ParallelScavenge關注的是高吞吐量;
  2. CMS關注的是低停頓時間;
  3. G1關注的是使用時間相對較短的停頓來達到很高的吞吐量,CMS的替代品,在超大堆上表現優異(eg:8g以上)。

4、GC發生時間:

    (1)MinorGC:大多數情況下,對象在新生代Eden區分配。當Eden區沒有足夠空間時,進行一次minorGC。如果是大對象,直接在老年代分配。

    (2)FullGC:

        a.系統主動調用System.gc(),不一定立即執行;

        b.老年代空間不足;

        c.方法區空間不足;

        d.通過Minor GC後進入老年代的平均大小大於老年代的可用內存;

        e.由Eden區、From Space區向To Space區複製時,對象大小大於To Space可用內存,則把該對象轉存到老年代,且老年代的可用內存小於該對象大小。

 

參考資料:《深入JAVA虛擬機》

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