Java 8+
-
序章
在 C/C++ 語言中,程式設計師自己分配記憶體、回收記憶體,不存在垃圾回收一說。
而在 Java 中,記憶體分配 絕大多數 是 JVM 的工作——棧記憶體、堆記憶體、永久代/元空間 等。ben釋出於部落格園
記憶體分配了就完了嗎?不。JVM 執行時 的 記憶體不是無限的,受制於 程式設計師配置、系統記憶體上限,因此,在有限的記憶體中,還要進行 垃圾回收。
棧記憶體、永久代/元空間 不需要 垃圾回收,垃圾回收的重點在於——堆記憶體。(本句 存疑,畢竟,不是100%瞭解 Java Memory Model、垃圾回收 等,官文、原始碼沒看過呢。)
近期看過幾篇 JVM、垃圾回收的博文,特總結記錄於此(總結了,才好提高嘛)。
ben釋出於部落格園
堆記憶體結構:(年輕代(Eden;Survivor(To;From;));老年代)。
假設堆記憶體有50MB,預設情況下,其不同區分配的記憶體為:
修改配置調整(調優)後,比例應該就不同了。ben釋出於部落格園
HotSpot Virtual Machine Garbage Collection Tuning Guide
https://docs.oracle.com/en/java/javase/21/gctuning/preface.html
#可下載pdf
官方文件,介紹了 HotSpot VM (JVM 的 Oracle 實現) 的 垃圾回收調優,涉及 各種 垃圾回收器。
當然,Java 8 也有:ben釋出於部落格園
https://docs.oracle.com/javase/8/
不過,沒有 PDF 下載了。
注,上面兩個文件作者也是第一次開啟,還沒細看。
垃圾回收演算法
》引用計數法:
存在迴圈引用問題。
英文:Reference Counting
》標記-清除演算法 Mark-Sweep
引用:首先標記出所有不需要回收的物件,在標記完成後統一回收掉所有沒有被標記的物件。
它是最基礎的收集演算法,後續的演算法都是對其不足進行改進得到。
效率問題、空間問題(碎片)。
#參考資料2
英文:Mark-Sweep
》複製演算法:
浪費記憶體。
不適合老年代。
英文:Copying Algorithm
》標記-整理演算法 Mark-Compact
另名,標記-壓縮演算法
引用:是根據 老年代的特點 提出的一種標記演算法,標記過程仍然與“標記-清除”演算法一樣,但後續步驟不是直接對可回收物件回收,
而是 讓所有存活的物件向一端移動,然後直接清理掉端邊界以外的記憶體。
#參考資料2
英文:Mark-Compact
》分代收集演算法 Generational Collection
引用:當前虛擬機器的垃圾收集都採用分代收集演算法,這種演算法沒有什麼新的思想,只是根據物件存活週期的不同將記憶體分為幾塊。
#參考資料2 文中還有 更多介紹。
引用:"分代收集演算法基於物件的存活時間,將堆記憶體分為幾代:
年輕代(Young Generation)、年老代(Old Generation)和永久代(Permanent Generation)。
各代使用不同的收集演算法。"
#參考資料6
英文:Generational Collection
說明,不同的垃圾回收演算法 可能是 來自一篇篇 學術論文。
垃圾回收器
》Serial:
單執行緒垃圾收集。ben釋出於部落格園
》ParNew:
Serial 收集器的多執行緒版本。
新生代採用標記-複製演算法,老年代採用標記-整理演算法。
英文:Par 是 Parallel 的縮寫。
》Parallel Scavenge
引用:也是使用標記-複製演算法的多執行緒收集器,它看上去幾乎和 ParNew 都一樣。
引用:Parallel Scavenge 收集器關注點是吞吐量(高效率的利用 CPU)。
引用:新生代採用標記-複製演算法,老年代採用標記-整理演算法。
引用:JDK1.8 預設使用的是 Parallel Scavenge + Parallel Old(下面)。
如果指定了-XX:+UseParallelGC 引數,則預設指定了-XX:+UseParallelOldGC,可以使用-XX:-UseParallelOldGC 來禁用該功能。
英文:Scavenge(英 [ˈskævɪndʒ] vt.& vi.清除汙物,打掃; (在廢物中)尋覓; (動物)食腐肉)
》Serial Old:
Serial 收集器的老年代版本。
》Parallel Old
Parallel Scavenge 收集器的老年代版本。ben釋出於部落格園
》CMS:
引用:CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標的收集器。它非常符合在注重使用者體驗的應用上使用。
引用:HotSpot 虛擬機器第一款真正意義上的【併發收集器】(不是 並行!)。
注意,出現了 Safepoint 概念。
已廢棄。
2020年3月:JDK14釋出,剔除了CMS收集器。
引用:CMS 垃圾回收器在 Java 9 中已經被標記為過時(deprecated),並在 Java 14 中被移除。
》G1
引用:G1 (Garbage-First) 是一款面向伺服器的垃圾收集器,主要針對配備多顆處理器及大容量記憶體的機器. 以極高機率滿足 GC 停頓時間要求的同時,還具備高吞吐量效能特徵。
引用:從 JDK9 開始,G1 垃圾收集器成為了預設的垃圾收集器。
》ZGC
這款收集器的名字就叫作 Z Garbage Collector。ben釋出於部落格園
引用:
ZGC 在 Java11 中引入,處於試驗階段。
ZGC 在 Java15 已經可以正式使用了。
官網:
1、https://wiki.openjdk.org/display/zgc/Main
2、https://docs.oracle.com/en/java/javase/21/gctuning/z-garbage-collector.html
Quote:
The Z Garbage Collector (ZGC) is a scalable low latency garbage collector. ZGC performs all expensive work concurrently, without stopping the execution of application threads for more than a millisecond. It is suitable for applications which require low latency. Pause times are independent of the heap size that is being used. ZGC works well with heap sizes from a few hundred megabytes to 16TB. |
》ShenandoahGC:
引用:Shenandoah GC 是一種低停頓的垃圾回收器,旨在解決傳統垃圾回收器在大型堆上產生的停頓時間過長的問題。它是 OpenJDK 專案的一部分,並在 Java 12 中首次引入。
博文:Java 21 將放棄分代 Shenandoah GC
釋出於 2023-06-17 23:22:06
https://cloud.tencent.com/developer/article/2296640
注,剛聽說,就廢棄了?ben釋出於部落格園
英文:Shenandoah([地名] [美國] 謝南多厄; [電影]烽火田園)
選擇垃圾回收器的考慮因素
堆記憶體 大小。
停頓時間(Full GC 導致的 STW(Stop The World)):使用者執行緒的停頓時間。
吞吐量:高效率的利用 CPU。ben釋出於部落格園
Minor GC vs Major GC vs Full GC
在 官文 HotSpot Virtual Machine Garbage Collection Tuning Guide 中可以搜尋到 minor gc, major gc, full gc 等概念。
注,下面是在 Release 21(Java 21) 的 pdf文件中 檢索。
搜尋:minor
Quote: When the young generation fills up, it causes a minor collection in which only the young generation is collected; garbage in other generations isn't reclaimed.
Quote: Eventually, the old generation fills up and must be collected, resulting in a major collection, in which the entire heap is collected.
搜尋 full:ben釋出於部落格園
引用:
Minor GC 是 清理 新生代中的Eden區, Survivor區滿時不會觸發 ; Major GC 是 清理 老年代 ; Full GC 是 清理整個堆和方法區,包括 年輕代、老年代和方法區。
來自 參考資料#4
ben釋出於部落格園
注,官網文件 作者還未細看,資訊或許不準確,請注意。
小結
Safepoint 的引入,實現了 併發垃圾收集。
Java 8 預設使用 Parallel Scavenge + Parallel Old。
Java 9+ 預設使用 G1(Garbage First)。
目前使用的是 Java 17,預設G1,也可以透過引數 -XX:+UseZGC 使用 ZGC。
列印GC執行 的引數:-XX:+PrintGCDetails。
2024年,重點關注 G1、ZGC 兩種,尤其是 預設的 G1。至於 比 Java 17 更高的版本,目前還沒用過。
ben釋出於部落格園
---END---
引用了不少其它博文的語句,如有冒犯,請通知作者刪除。
水平非常有限,如有錯漏,請不吝告知。
謝謝。
本文連結:
https://www.cnblogs.com/luo630/p/18445951
參考資料
1、1.大白話帶你認識 JVM
https://javaguide.cn/java/jvm/jvm-intro.html
2、JVM垃圾回收詳解(重點)
https://javaguide.cn/java/jvm/jvm-garbage-collection.html
3、G1、ZGC、ShenandoahGC 高效能收集器深入剖析
Java全棧架構師的文章 - 知乎
https://zhuanlan.zhihu.com/p/624386102
釋出於 2023-04-24 10:13
4、Minor GC、Major GC、Full GC的區別
釋出於 2021-07-21 10:46:46
https://cloud.tencent.com/developer/article/1850327
5、官方文件:HotSpot Virtual Machine Garbage Collection Tuning Guide
6、深入理解Java的垃圾回收機制(GC)實現原理
2024-06-14
https://developer.aliyun.com/article/1537550
7、探索JVM垃圾回收演算法:選擇適合你應用的最佳GC策略
2024-08-16
https://developer.aliyun.com/article/1588394
8、
ben釋出於部落格園
ben釋出於部落格園