GC算法

GC簡介
一. 爲什麼要有GC策略原理?
a) 在工作和研究過程中不可避免的會遇到內存溢出與內存泄露的問題
二. GC解決了哪些問題
a) 那些對象可以被回收
b) 什麼時候去回收這些對象
c) 採用什麼樣的方式回收
三. GC算法
a) 引用計數算法:引用計數歸零時回收
i. 優點:效率高、
ii. 缺點:對循環引用的對象無法進行回收
b) 跟搜索算法 設立若干跟對象,當任何一個跟對象到某一個對象不可達時,則認爲這個對象是可以清楚的

c) GC roots(GC根)在java語言中,可以當做GC roots的對象
i. 虛擬機棧中的引用對象 本地變量
ii. 方法區中的靜態屬性引用的對象
iii. 方法區中的常量引用的對象 final修飾的常量值
iv. 本地方法棧中JNI的引用對象 本地變量
d) 垃圾回收算法:
i. 標記清除法

  1. 當堆中的有效內存快要耗盡時,就會停止整個程序,然後進行標記和清除
  2. 標記:遍歷所有的GC roots 然後將所有GC roots可達的對象標記爲存活的對象
  3. 清除:將遍歷堆中所有的對象全部清除掉
  4. 分析:
    a) 運行過程
    在這裏插入圖片描述

程序運行時的狀態,他們的標誌位都是0,如果內存耗盡就會發生下圖
在這裏插入圖片描述
根據跟搜索算法 所有root對象可達的對象全部被標記爲存活的對象,此時第一步標記就結束了
在這裏插入圖片描述
沒有標記的對象就會被回收,而被標記的將會留下並且重新歸0
喚醒停止的線程,讓程序繼續進行
b) 爲什麼要讓線程中止?
如果未中止當標記結束之後此時程序New一個新的對象,則這個新創建的的對象就會被清除
c) 缺點:
i. 效率低 遞歸和全堆的遍歷 在gc進行的時候要中止進程
ii. 清理出來的空閒內存是不連續的,爲了解決這個問題JVM就不得不維持一個空閒的列表
ii. 複製算法:複製算法將內存劃分爲兩個區間,在任意時間點,所有動態分配的對象只能在其中一個區間(活動區間),而另一個區間(空閒空間)則是空閒的

  1. 當活動區間內存耗盡時JVM將暫停程序運行,開啓複製算法GC線程,接下來GC線程會將活動區間內的存貨對象全部複製到空閒空間並且按照內存地址一次排列,與此同時,GC線程將更新存活對象的內存地址指向新的內存地址
  2. 空閒空間和活動區間交換了,垃圾對象現在全部留在原來的火工空間,也就是現在的空閒空間,事實上在空閒空間和活動空間交換時垃圾對象就一次被回收了
  3. 優缺點:
    a) 相比於標記清除算法,內存混亂的缺點
    b) 浪費一半的內存
    c) 假設對象存活率高 複製用的時間將特別長
    d) 在對象成活率低的時候 內存浪費太嚴重了
    iii. 標記整理法 標記+整理
  4. 標記: 遍歷GC roots 將存活的對象標記
  5. 整理:移動所有存活的對象,且按照內存地址依次,最後將內存末端以後的地址清除
    在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述

標記存活的對象將會被整理,按照內存地址一次排序,未被標記的清除,當我們需需要給新對象分配內存時,jvm只需要吃有一個內存的起始地址即可,這比維護一個空閒列表少了不少開銷
3. 缺點:效率低 不但要標記存活的對象還有整理存活對象的地址
四. 三種算法的比較
a) 三個算法都是基於跟搜索算法去判斷一個對象是否應該被回收
b) GC線程啓用時都要暫停應用程序
c) 效率:
i. 內存整齊度:複製算法=標記整理法>標記清除法
ii. 內存利用率:標記整理法>標記清法>複製算法

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