1. 程式人生 > >一篇文章讓你了解GC垃圾回收器

一篇文章讓你了解GC垃圾回收器

存滿 需要 進行 並行 mil 之間 consola 微軟雅黑 並行執行

簡單了解GC垃圾回收器

了解GC之前我們首先要了解GC是要做什麽的?顧名思義回收垃圾,什麽是垃圾呢?

GC回收的垃圾主要指的是回收堆內存中的垃圾對象。

從根對象出發,所有被引用的對象,都是存活對象 其他對象,都是垃圾對象。

根對象:

   棧中的引用變量,所引用的對象。

  方法區經靜態變量所引用的對象。

GC回收的三種基本方式

一、標記-清除

  標記存活對象,清理其他垃圾對象(陰影為存活對象,空白為垃圾對象)

  優點:效率高

  缺點:產生碎片,使內存分布碎片化,造成內存空間不連續。若出現大的對象,內存空間不連續則難以存取

技術分享圖片

二、標記-整理

  標記存活對象,清除垃圾對象,對垃圾對象進行整理

  優點:沒有碎片

   缺點:效率低

技術分享圖片

三、復制

  在內存中分配兩塊內存,將標記的存活對象復制到另一塊內存當中,

  再將原內存的對象清除。

  優點:效率高

  缺點:浪費內存

技術分享圖片

內存分區

  新生代

  老年代

  永久代(方法區)(在Java8中,永久代已經被移除,被一個稱為“元數據區”(元空間)的區域所取代)

新生代

  主要是用來存放新生的對象。一般占據堆的1/3空間。由於頻繁創建對象,所以新生代會頻繁觸發MinorGC進行垃圾回收

新生代又分為伊甸園與生存區,生存區分為ServivorFrom、ServivorTo

  • Eden區(伊甸園):Java新對象的出生地(如果新創建的對象占用內存很大,則直接分配到老年代)。當Eden區內存不夠的時候就會觸發MinorGC,對新生代區進行一次垃圾回收。
  • ServivorTo:保留了一次MinorGC過程中的幸存者。
  • ServivorFrom:上一次GC的幸存者,作為這一次GC的被掃描者。

過程:

新建對象,在伊甸園分配內存

伊甸園存滿,復制到from

from存滿,復制到to,並交換角色

對象在fromto之間復制15次,晉升到老年代

技術分享圖片

老年代

   標記-清除、標記-整理

  間隔一段時間,會執行一次小範圍垃圾回收

  當老年代空間占用到一定比例 0.85,會執行full-gc

   當老年代也滿了裝不下的時候,就會拋出OOM(Out of Memory)異常。

常見的垃圾回收器

  1. 串行垃圾回收器(Serial Garbage Collector)
  2. 並行垃圾回收器(Parallel Garbage Collector)
  3. 並發標記掃描垃圾回收器(CMS Garbage Collector)
  4. G1垃圾回收器(G1 Garbage Collector)

了解主要的兩種(CMS,G1)

CMS - 並發的標記-清除

  STW(Stop The World)時間非常短暫

  初始標記(stw)

  只標記根對象

  並發標記

  垃圾回收器,與其他java程序並行執行

  重新標記(stw)

  並發清除

  與其他java程序並行執行,配置參數過多,使用過於復雜

總結:

  是一種以獲得最短回收停頓時間為目標的收集器,基於標記清除算法。過程如下:初始標記,並發標記,重新標記,並發清除,

  優點是並發收集,低停頓,缺點是對CPU資源非常敏感,無法處理浮動垃圾,收集結束會產生大量空間碎片。

G1 - Garbage First

  內存被劃分成幾千個內存塊

   有伊甸園、生存區、老年代

   用復制算法

   G1會找到垃圾最多的內存塊,優先回收

  配置參數非常簡單,只需要配置目標停頓時間(stw)G1自動調整其他參數,來達到預期的停頓時間

總結:G1垃圾回收器適用於堆內存很大的情況,他將堆內存分割成不同的區域,並且並發的對其進行垃圾回收。G1也可以在回收內存之後對剩余的

   堆內存空間進行壓縮。並發掃描標記垃圾回收器在STW情況下壓縮內存。G1垃圾回收會優先選擇第一塊垃圾最多的區域

一篇文章讓你了解GC垃圾回收器