91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JVM垃圾回收算法的原理是什么

發布時間:2021-06-11 16:49:39 來源:億速云 閱讀:148 作者:Leah 欄目:編程語言

JVM垃圾回收算法的原理是什么,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

在JVM內存模型中會將堆內存劃分新生代、老年代兩個區域,兩塊區域的主要區別在于新生代存放存活時間較短的對象,老年代存放存活時間較久的對象,除了存活時間不同外,還有垃圾回收策略的不同,在JVM中中有以下回收算法:

  • 標記清除

  • 標記整理

  • 復制算法

  • 分代收集算法

有了垃圾回收算法,那JVM是如果確定對象是垃圾對象的呢?判斷對象是否存活JVM也會有幾套自己判斷算法了:

  • 引用記數

  • 可達性分析

有了垃圾回收和判斷對象存在這兩個概念后,再來逐步分析它們。

JVM是如何判斷對象是否存活的?

要是讓開發人員來判斷一個對象是否有用是很簡單的,簡單的說就是:對象沒有任何引用就認為該對象可以被回收了。假設有如下程序代碼:

public class App {

 public static void main(){
  checkFile("/");
 }

 public static boolean checkFile(String path ){
  File file = new File(path);
  return file.exists();
 }
}

程序執行起來在調用checkFile的時候JVM圖大概像這樣:

JVM垃圾回收算法的原理是什么

到checkFile方法執行完成之后,它里面的局部變量file就會隨著棧幀一起被清理,這個時候還存活在JVM堆中的File對象也是無用的了:

JVM垃圾回收算法的原理是什么

要是人為來判斷非常清晰的就發現File對象已經無用了,那換成JVM它又是如何來判斷對象是否能存活的呢?

引用記數

引用記數算法原理比較簡單,想象下有個對象它有一個count屬性,每次引用該對象都會使count加1,假設JVM在判斷該對象是否存活的時候去檢查這個count屬性,發現這個屬性不為0說明還有其他對象在引用該對象。

JVM垃圾回收算法的原理是什么

等到checkFile方法執行完之后count就會減1變成0:

JVM垃圾回收算法的原理是什么

這樣一來JVM就很容易判斷一個對象是否存活了。

但是引用記數有一個明顯的缺點,就是無法解決循環引用的問題比如:A --> B --> A 這樣的對象關系它是沒有辦法來判斷對象是否該不該回收的。

GC Root(可達性分析)

為什么會被稱為可達性分析算法呢?可以這樣理解如果通過GC Root能到達一個對象那么這個對象就是存活的。那什么樣的對象才是GC Root呢?

在Java語言中,可作為GC Roots的對象包括下面幾種:

  1. 虛擬機棧中引用的對象(棧幀中的本地變量表);

  2. 方法區中類靜態屬性引用的對象;

  3. 方法區中常量引用的對象;

  4. 本地方法棧中JNI(Native方法)引用的對象。

還是用上面的例子,在checkFile方法執行時,因為棧幀變量file可做為GC Root所以在執行期間JVM是絕對不會回收掉這個File對象:

JVM垃圾回收算法的原理是什么

但是等到checkFile執行完成之后,這個棧幀會被彈出,其中的變量也會被釋放,相應的沒有GC Root能到達堆中的File對象,這個時候就可以判斷這個對象是一個無用的對象了,然后安全回收。

垃圾收回算法

標記清除

這種算法分兩分:標記、清除兩個階段,

標記階段是從根集合(GC Root)開始掃描,每到達一個對象就會標記該對象為存活狀態,清除階段在掃描完成之后將沒有標記的對象給清除掉。

用一張圖說明:

JVM垃圾回收算法的原理是什么

這個算法有個缺陷就是會產生內存碎片,如上圖B被清除掉后會留下一塊內存區域,如果后面需要分配大的對象就會導致沒有連續的內存可供使用。

標記整理

標記整理就沒有內存碎片的問題了,也是從根集合(GC Root)開始掃描進行標記然后清除無用的對象,清除完成后它會整理內存。

JVM垃圾回收算法的原理是什么

這樣內存就是連續的了,但是產生的另外一個問題是:每次都得移動對象,因此成本很高。

復制算法

復制算法會將JVM推分成二等分,如果堆設置的是1g,那使用復制算法的時候堆就會有被劃分為兩塊區域各512m。給對象分配內存的時候總是使用其中的一塊來分配,分配滿了以后,GC就會進行標記,然后將存活的對象移動到另外一塊空白的區域,然后清除掉所有沒有存活的對象,這樣重復的處理,始終就會有一塊空白的區域沒有被合理的利用到。

JVM垃圾回收算法的原理是什么

兩塊區域交替使用,最大問題就是會導致空間的浪費,現在堆內存的使用率只有50%。

分代回收

新生代回收

JVM的堆分為新生代和老年代,兩種類型有不同的特性,根據它們的特性來選擇不同的回收算法,這種算法會將新生代劃分為一塊Eden和二個Survivor區:

JVM垃圾回收算法的原理是什么

如上面的圖有三塊區域它們會按照8:1:1的比例進行分配,如1000m的堆Eden是800m,二個Survivor各占100m,那它們是如何運行的呢?

  1. 始終會有一塊Survivor是空著的,內存使用率是90%

  2. 程序運行會在Eden和其中一塊Survivor 1中分配內存

  3. 等到執行Minor gc,會將存活下來的對象移動到空著的Survivor 2中

  4. 然后在Eden和Survivor 2中繼續分配內存,Survivor 1空著等著下次使用

看完上述內容,你們掌握JVM垃圾回收算法的原理是什么的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

jvm
AI

永宁县| 夏津县| 米泉市| 建昌县| 泰州市| 丹阳市| 同德县| 来宾市| 南昌市| 东辽县| 天等县| 富锦市| 通海县| 海伦市| 连平县| 岐山县| 洮南市| 贡山| 杨浦区| 金乡县| 辉南县| 额尔古纳市| 会宁县| 辽宁省| 灵璧县| 龙游县| 濮阳县| 江门市| 翁源县| 靖安县| 溧阳市| 岱山县| 罗江县| 甘洛县| 治县。| 惠安县| 米林县| 韶山市| 新乐市| 大悟县| 五台县|