什么是自動垃圾回收?
自動垃圾回收是一種在堆記憶體中找出哪些物件在被使用,還有哪些物件沒被使用,并且將后者刪掉的機制,
所謂使用中的物件(已參考物件),指的是程式中有指標指向的物件;而未使用中的物件(未參考物件),則沒有被任何指標給指向,因此占用的記憶體也可以被回收掉,
在用 C 之類的編程語言時,程式員需要自己手動分配和釋放記憶體,而 Java 不一樣,它有垃圾回收器,釋放記憶體由回收器負責,本文接下來將介紹垃圾回識訓制的基本程序,
第一步:標記
垃圾回收的第一步是標記,垃圾回收器此時會找出哪些記憶體在使用中,還有哪些不是,
上圖中,藍色表示已參考物件,橙色表示未參考物件,垃圾回收器要檢查完所有的物件,才能知道哪些有被參考,哪些沒,如果系統里所有的物件都要檢查,那這一步可能會相當耗時間,關注Java技術堆疊微信公眾號,回復:JVM46,可以獲取一份超全 JVM 調優攻略,
第二步:清除
這一步會刪掉標記出的未參考物件,
記憶體分配器會保留指向可用記憶體的參考,以供分配新物件,
壓縮
為了提升性能,洗掉了未參考物件后,還可以將剩下的已參考物件放在一起(壓縮),這樣就能更簡單快捷地分配新物件了,
為什么需要分代垃圾收集?
之前說過,逐一標記和壓縮 Java 虛擬機里的所有物件非常低效:分配的物件越多,垃圾回收需時就越久,不過,根據統計,大部分的物件,其實用沒多久就不用了,JVM 與 Linux 的記憶體關系詳解,這篇推薦閱讀,
來看個例子吧,(下圖中,豎軸代表已分配的位元組,而橫軸代表程式運行時間)

上圖可見,存活(沒被釋放)的物件隨運行時間越來越少,而圖中左側的那些峰值,也表明了大部分物件其實都挺短命的,
JVM 分代
根據之前的規律,就可以用來提升 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中的物件分配和老化程序,關注Java技術堆疊微信公眾號,回復:JVM46,可以獲取一份超全 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,清理并最終壓縮該空間,

關注Java技術堆疊微信公眾號,在后臺回復關鍵字:Java,可以獲取一份堆疊長整理的 Java 最新技術干貨,
原文:https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
譯文:https://www.oschina.net/translate/java-gc
翻譯:Rhys_Lee, AzureSora, 溪邊九節, 小小菜鳥雞
推薦去我的博客閱讀更多:
1.Java JVM、集合、多執行緒、新特性系列教程
2.Spring MVC、Spring Boot、Spring Cloud 系列教程
3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程
4.Java、后端、架構、阿里巴巴等大廠最新面試題
覺得不錯,別忘了點贊+轉發哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/185741.html
標籤:Java
