JVM的垃圾回收機制

JVM中的垃圾回收機制:

JVM中的分代模型,根據object對象的存在時間分成了三種代

年輕代、老年代、持久代

年輕代中分爲兩大空間,Eden和S層(也就是存活層),存活層S分爲兩部分S0、S1.
官方建議年老代是年輕代的兩倍

在這裏插入圖片描述

年輕代的object對象要到年老代的三種方式:

  1. object對象經歷了默認的15次GC還在活躍就會被移動到年老代
  2. object對象超出設置的參數也會被移動到年老代
  3. 當存活區中有一個區中活躍的object充滿了這個區,那麼這個區中的所有object對象都會被移動到年老代

剛創建的對象大部分會存放在Eden中,當Eden中的內存要滿了之後,就會發生一次full GC,將Eden中的不活躍的對象,也就是沒有再用到的對象給銷燬,將還在用到的object對象給移動到存活區S0。此時Eden和S1是空的,然後再第二輪再創建對象繼續GC,將Eden中和存活區S0中的對象移動到S1,然後此時Eden和S0都是空的,S1中都是還在活躍用到的對象。這就是著名的“停止複製”算法

然後當object中對象在經歷了15次full GC的時候(這個是JVM中默認設置的一個參數),就會被移動到老年代,當object中的對象足夠大的時候也會被移動到老年代,老年代的object如果要被銷燬的話,是要先標記-再銷燬的。老年代的空間的容量要比年輕代的空間容量要大,而且老年代GC的次數也會比年輕代GC的次數要少的多。

如果老年代中要加入的一個object對象大小大於此時老年代中的存儲空間的話,也會發生一次GC。

老年代中會維護一個512byte的塊,存放的是老年代要引用的年輕代中的object,若老年代中的object對象要用到年輕代中的object對象,當young GC的時候,只會遍歷這裏,就不會遍歷老年代的object對象了

持久代中存放常量池,靜態常量,可序列化的對象等。

當發生一次full GC的時候,也會銷燬掉持久代中的可銷燬的對象。

可銷燬的對象:也就是遍歷root節點,從上往下遍歷這顆樹,如果找到沒有連接的object對象,那麼這個對象就是可被銷燬的。

在這裏插入圖片描述

這裏面的紅色部分就是可以被銷燬的object對象。


以上部分是JDK1.7以前的版本

方法區中存放常量池、字段和方法數據、構造函數和普通方法的字節碼內容、還包括一些在類、實例、接口初始化時用到的特殊方法。平常人們將永久帶和方法區是等同的。但是方法區是標準,永久帶是實現。這就相當於你將Java中的接口和接口的實現等同對待了一樣。

接下來說JDK1.8之後的版本(包含JDK1.8)

JDK1.8之後將永久帶給移除了,用新出現的元空間來代替了永久帶。因爲永久帶用到的是內存,而元空間用到的是本地磁盤,這樣更加安全

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