天天看點

了解中的jvm記憶體模型裡的垃圾回收

這裡整理一下自己對jvm記憶體垃圾回收的一點認識,不一定詳細也不一定就正确,隻是自己的經驗積累隻談而已。

jvm标記查找方式:ROOT Search即可達根查找法

jvm垃圾回收算法:标記,複制,标記壓縮 (新生代采用複制算法,老年代采用标記或标記壓縮都比較耗時,但是标記壓縮避免了記憶體碎片)

jvm垃圾收集器各廠商不同而不同,主要分為單例,并行,并發(CMS,jdk1.8預設),G1(1.9預設),ZGS等,如下逐一介紹:

單例:絕對的STOP WORLD,一個單線程回收,垃圾查找及回收過程都需要業務線程stop,大記憶體情況下非常耗時

并行:絕對的STOP WORLD,多個線程回收,垃圾查找及回收過程都需要業務線程stop,依然避免不了大記憶體垃圾的耗時

CMS并發:

   多個垃圾回收線程和業務工作線程可以同時工作,CMS理論上為了解決stop world問題,但是它采用的三色标記算法存在漏标的現象

   (引用發生變化正好此垃圾回收線程被cpu挂起又開始執行這段時間裡),CMS為了解決漏标的問題采用了remark操作,就是最後再進行一次全面的從新查找,這樣在記憶體巨大的時候依然會發生嚴重的stop world現在。

G1:

    G1為了解決CMS的問題,采用了在引用發生變化的時候将那個消失的指針向量記錄到垃圾回收線程的堆棧裡(記憶體屏障裡的寫屏障實作),當垃圾回收線程重新擷取cpu執行時間時候會先去這個堆棧裡将裡面的記錄的那個沒有引用的對象找出來,然後以它為root進行反查找(不是标記)看有沒有對象指向它,若有說明它不是垃圾,若沒有就說明它确實是垃圾。

      G1實體上采用了region分區的方式,雖然它邏輯上依然采用了分段記憶體,但是實體上是沒有分段的,這個是很大的差別,它把整個jvm記憶體分為多個小的region實體邏輯,在并發垃圾回收裡就可以很快的對各個小的region進行标記回收等動作,而且對回收的region動态作用于新生代或老年代對象存儲。

總之:1.G1即避免了CMS裡remark操作的Stop World現象(垃圾回收線程裡寫入因變化而消失的指針)

          2.實體上的region分區,可以提高并發垃圾回收情況下的效率。

補充:

1.三色标記算法:

  白色-》沒有被标記(可能是垃圾)

  灰色-》部分引用的子對象被标記了,部分還沒來的急标記,它自己也不是垃圾,垃圾回收線程再回來标記的時候需要從此位置繼續标記

  黑色-》所有引用的子對象都已經被标記過了,就認為此對象已經标記了不是垃圾,垃圾回收線程再回來标記的時候不需要從此位置标記

2.漏标:

了解中的jvm記憶體模型裡的垃圾回收

繼續閱讀