圖解 Java 垃圾回收機制,寫得非常好!
原文:
譯文:
翻譯:Rhys_Lee, AzureSora, 溪邊九節, 小小菜鳥雞
Java架構/分散式:705127209(大牛交流群)沒有開發經驗勿加!
什麼是自動垃圾回收?
自動垃圾回收是一種在堆記憶體中找出哪些物件在被使用,還有哪些物件沒被使用,並且將後者刪掉的機制。
所謂使用中的物件(已引用物件),指的是程式中有指標指向的物件;而未使用中的物件(未引用物件),則沒有被任何指標給指向,因此佔用的記憶體也可以被回收掉。
在用 C 之類的程式語言時,程式設計師需要自己手動分配和釋放記憶體。而 Java 不一樣,它有垃圾回收器,釋放記憶體由回收器負責。本文接下來將介紹垃圾回收機制的基本過程。
第一步:標記
垃圾回收的第一步是標記。垃圾回收器此時會找出哪些記憶體在使用中,還有哪些不是。
上圖中,藍色表示已引用物件,橙色表示未引用物件。垃圾回收器要檢查完所有的物件,才能知道哪些有被引用,哪些沒。如果系統裡所有的物件都要檢查,那這一步可能會相當耗時間。
第二步:清除
這一步會刪掉標記出的未引用物件。
記憶體分配器會保留指向可用記憶體的引用,以供分配新物件。
壓縮
為了提升效能,刪除了未引用物件後,還可以將剩下的已引用物件放在一起(壓縮),這樣就能更簡單快捷地分配新物件了。
為什麼需要分代垃圾收集?
之前說過,逐一標記和壓縮 Java 虛擬機器裡的所有物件非常低效:分配的物件越多,垃圾回收需時就越久。不過,根據統計,大部分的物件,其實用沒多久就不用了。
來看個例子吧。(下圖中,豎軸代表已分配的位元組,而橫軸代表程式執行時間)
上圖可見,存活(沒被釋放)的物件隨執行時間越來越少。而圖中左側的那些峰值,也表明了大部分物件其實都挺短命的。
JVM 分代
根據之前的規律,就可以用來提升 JVM 的效率了。方法是,把堆分成幾個部分(就是所謂的分代),分別是新生代、老年代,以及永生代。
新物件會被分配在新生代記憶體。一旦新生代記憶體滿了,就會開始對死掉的物件,進行所謂的 小型垃圾回收 過程。一片新生代記憶體裡,死掉的越多,回收過程就越快;至於那些還活著的物件,此時就會老化,並最終老到進入老年代記憶體。
Stop the World 事件—— 小型垃圾回收屬於一種叫 "Stop the World" 的事件。在這種事件發生時,所有的程式執行緒都要暫停,直到事件完成(比如這裡就是完成了所有回收工作)為止。
老年代用來儲存長時間存活的物件。通常,設定一個閾值,當達到該年齡時,年輕代物件會被移動到老年代。最終老年代也會被回收。這個事件成為 Major GC。
Major GC 也會觸發STW(Stop the World)。通常,Major GC會慢很多,因為它涉及到所有存活物件。所以,對於響應性的應用程式,應該儘量避免Major GC。還要注意,Major GC的STW的時長受年老代垃圾回收器型別的影響。
永久代包含JVM用於描述應用程式中類和方法的後設資料。永久代是由JVM在執行時根據應用程式使用的類來填充的。此外,Java SE類庫和方法也儲存在這裡。
如果JVM發現某些類不再需要,並且其他類可能需要空間,則這些類可能會被回收。
世代垃圾收集過程
現在你已經理解了為什麼堆被分成不同的代,現在是時候看看這些空間是如何相互作用的。 後面的圖片將介紹JVM中的物件分配和老化過程。
首先,將任何新物件分配給 eden 空間。 兩個 survivor 空間都是空的。
當 eden 空間填滿時,會觸發輕微的垃圾收集。
引用的物件被移動到第一個 survivor 空間。 清除 eden 空間時,將刪除未引用的物件。
在下一次Minor GC中,Eden區也會做同樣的操作。刪除未被引用的物件,並將被引用的物件移動到Survivor區。然而,這裡,他們被移動到了第二個Survivor區(S1)。
此外,第一個Survivor區(S0)中,在上一次Minor GC倖存的物件,會增加年齡,並被移動到S1中。待所有幸存物件都被移動到S1後,S0和Eden區都會被清空。注意,Survivor區中有了不同年齡的物件。
在下一次Minor GC中,會重複同樣的操作。不過,這一次Survivor區會交換。被引用的物件移動到S0,。倖存的物件增加年齡。Eden區和S1被清空。
此幻燈片演示了 promotion。 在較小的GC之後,當老化的物體達到一定的年齡閾值(在該示例中為8)時,它們從年輕一代晉升到老一代。
隨著較小的GC持續發生,物體將繼續被推廣到老一代空間。
所以這幾乎涵蓋了年輕一代的整個過程。 最終,將主要對老一代進行GC,清理並最終壓縮該空間。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69912582/viewspace-2647461/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 圖解Golang垃圾回收機制!圖解Golang
- java垃圾回收機制Java
- Java 垃圾回收機制Java
- java垃圾回收機制整理Java
- java JVM垃圾回收機制JavaJVM
- 理解 Java 垃圾回收機制Java
- Java的垃圾回收機制Java
- Java 垃圾回收機制概念梳理Java
- PHP 垃圾回收機制詳解PHP
- Java虛擬機器 —— 垃圾回收機制Java虛擬機
- Java的垃圾回收(Garbage Collection)機制Java
- Java虛擬機器5:Java垃圾回收(GC)機制詳解Java虛擬機GC
- JAVA垃圾回收機制和Python垃圾回收對比與分析JavaPython
- Python垃圾回收機制詳解Python
- C#垃圾回收機制詳解C#
- 詳解Python垃圾回收機制Python
- js垃圾回收機制JS
- javascript 垃圾回收機制JavaScript
- JVM 垃圾回收機制JVM
- JVM垃圾回收機制JVM
- java垃圾回收器的工作機制Java
- 圖解Java記憶體回收機制圖解Java記憶體
- Java垃圾回收機制詳解及效能最佳化詳解。Java
- JVM之垃圾回收機制詳解分析JVM
- 簡單瞭解JavaScript垃圾回收機制JavaScript
- 剖析垃圾回收機制(上)
- Python垃圾回收機制Python
- JavaScript的垃圾回收機制JavaScript
- PHP的垃圾回收機制PHP
- jvm的垃圾回收機制JVM
- jvm垃圾回收機制 一JVM
- jvm垃圾回收機制 二JVM
- JS的垃圾回收機制JS
- 一文學會 Java 垃圾回收機制Java
- PHP的垃圾回收機制-回收週期PHP
- Java虛擬機器系列之垃圾回收機制(2)Java虛擬機
- Java教程分享:JVM垃圾回收機制之物件回收演算法JavaJVM物件演算法
- 如何回答Android面試中java垃圾回收機制Android面試Java