java虛擬機(五)--垃圾回收機制GC

什麼樣的對象須要回收

  若是對象已經死亡了,就能夠進行回收,判斷方式以下java

  1).引用計數器:給對象添加一個計數器,有地方引用,就+1,當引用失效,就-1。當計數器爲0時,判斷對象不能再使用,可是當對象相互引算法

用的時候沒法進行GC數據結構

  1).可達性算法:從GC Roots開始,到對象之間有引用鏈相連,就是可達的。HotSpot採用可達性算法,商用虛擬機沒有采用引用計數器jvm

GC Roots有哪些:spa

   1).局部變量表中引用的對象線程

  2).棧幀中常量引用的對象對象

  3).棧幀中static引用的對象生命週期

  4).JNI引用的對象內存

  5).類加載器字符串

  6).Thread

垃圾回收算法

  1).標記清除:對不具備可達性的對象進行標記,而後進行統一回收,最基本的GC算法

  缺點:標記和清除兩個階段效率都不高,會產生大量不連續的內存碎片,在給大對象分配內存的時候,可能沒法找到連續的內存,而不得不提

前進行GC

  2).複製:把內存分紅相同兩部分,每次使用一部分,GC的時候把可用對象複製到另外一邊,而後把使用的一邊直接清理掉,不會產生內存碎片,

可是直接浪費了一半內存,代價太巨大了。

  3).標記整理:若是對象存活率比較高的時候,複製算法的效率就會下降,並且須要有額外的空間進行分擔擔保,老年代就不可能使用對存活

對象進行標記以後,而後把存活的對象都向一端移動,直接清理邊界之外的內存

  4).分帶收集:當前商用VM採用的GC算法,新生代使用複製算法,老年代使用另外兩個。

  商用虛擬機的新生代都是採用複製算法,新生代的對象98%生命週期都很短,每次使用Eden Space和From Survivor,把這兩塊區域存活的對象

複製到To Survivor,而後清理內存,Eden Space:From Survivor=8:1,這樣每次只會浪費10%內存,當To Survivor內存空間不夠的時候,使用老年

代。

HotSpot的算法實現

  可達性分析從GC Roots節點找引用鏈時,會發生GC停頓,是指分析期間中止其餘全部的線程,若是分析過程當中對象引用關係還在變化,準確性

沒法獲得保證。

  主流jvm採用準確式GC,HotSpot中經過一組OopMap的數據結構知道哪些地方存放着對象引用,就能夠快速、準確完成GC枚舉。

  新生代和老生代默認的空間佔比分別是是1/三、2/3。

複製算法的執行流程以下

  一、把Eden + From Survivor存活的對象放入To Survivor區;

  二、清空Eden和From Survivor分區;

  三、From Survivor和To Survivor分區交換。

  四、每次在From Survivor到To Survivor移動時都存活的對象,年齡就+1,當年齡到達15(默認配置是15)時,升級爲老年代。大對象也會

直接進入老年代。

  老年代當空間佔用到達某個值以後就會觸發全局垃圾收回,通常使用標記整理的執行算法。

方法區回收(jdk1.8以前永久帶實現了方法區,而在jdk1.8廢棄永久帶,經過本地內存實現)

  對方法區回收也能夠說是對永久帶回收,主要針對兩部分:

  一、廢棄的常量:例如一個字符串"abc"在常量池中,可是沒有任何String對象引用它,進行GC的話,就須要被清理出常量池,類、方法、字段

的符號引用也是相同的

  二、無用的類:

    1).該類的全部實例都已經被GC

    2).加載該類的ClassLoader被GC

    3).該類對應java.lang.class對象沒有被任何地方引用,也就是沒法經過反射獲得該類的方法。

引用:

  就是自己保存的數據是另外一塊內存的起始地址

分類

  一、強引用:相似於new一個對象對應的引用,只要具備可達性,不會被回收

  二、軟引用:軟引用關聯的對象,在內存溢出發生之前,這些對象會被回收。能夠經過SoftReference實現軟引用

  三、弱引用:只能活到下次GC以前,當進行垃圾回收的時候,它確定死了。能夠經過WeakReference實現軟引用

  四、虛引用:最弱的一種引用關係。爲對象設置虛引用惟一目的就是能在對象被GC的時候收到一個系統通知。能夠經過PhantPhantomReference

實現軟引用

相關文章
相關標籤/搜索