JVM的垃圾處理機制詳解
JVM的垃圾處理機制
一、垃圾回收的流程
JVM 的垃圾回收(Garbage Collection, GC)大體分為兩步:
- 可達性分析(找到誰是垃圾)
- 垃圾回收算法(使用合適的算法處理垃圾)
二、可達性分析
可達性分析用來判斷一個對象是否還存活。
JVM 會從一些 GC Roots(如虛擬機棧中的局部變量、方法區(qū)的靜態(tài)變量、本地方法棧中的引用等)開始向外搜索,如果能通過引用鏈找到某個對象,那么該對象就是“可達”的,不會被回收;反之,就是“垃圾”。
需要注意:對象被標記為垃圾后,并不會立刻清除,而是等到下一次觸發(fā) GC 時才會被統(tǒng)一清理。
三、垃圾回收算法
常見的 GC 基礎(chǔ)算法有三種:
標記-清除(Mark-Sweep)
- 過程:先標記所有存活對象,再清理未標記的垃圾對象。
- 缺點:會產(chǎn)生 內(nèi)存碎片。
復制(Copying)
- 過程:將存活對象復制到另一塊內(nèi)存區(qū)域,清空原區(qū)域。
- 優(yōu)點:速度快,沒有碎片。
- 缺點:理論上浪費一半空間。
- 實際 JVM 中,新生代采用 Eden + 兩個 Survivor 區(qū)(常見比例 8:1:1),大大提高了利用率。
標記-整理(Mark-Compact)
- 過程:標記存活對象后,將它們移動到一邊,保持內(nèi)存連續(xù),再清理邊界之外的垃圾。
- 優(yōu)點:解決碎片問題。
- 缺點:移動對象需要額外開銷。
四、分代收集
不同算法各有優(yōu)劣,JVM 采用 分代收集(Generational GC) 的思想:
新生代
- 大多數(shù)對象朝生夕死。
- 使用 復制算法,快速回收。
- 新生代進一步劃分為 1 個 Eden 區(qū)和2 個 Survivor 區(qū)。
- 對象先分配在 Eden,經(jīng)過多次 Minor GC 存活下來的對象晉升到老年代。
老年代
- 存放生命周期較長的對象。
- 使用 標記-整理算法(或標記-清除 + 整理)。
- 避免來回復制帶來的性能損耗。
大對象
- 一些特別大的對象可能會直接分配到老年代,避免在新生代中頻繁復制。
五、現(xiàn)代 GC 收集器
在實際 JVM 中,基礎(chǔ)算法往往會被組合和優(yōu)化,形成不同的收集器:
1. Serial GC
- 特點:單線程,GC 時 Stop-The-World。
- 算法:新生代用復制算法,老年代用標記-整理。
- 適用場景:小應用、單核 CPU。
2. Parallel GC(吞吐量優(yōu)先)
- 特點:多線程并行回收,追求吞吐量最大化。
- 適用場景:后臺計算、大數(shù)據(jù)處理。
- 缺點:GC 停頓仍然較長。
3. CMS(Concurrent Mark-Sweep)
- 特點:并發(fā)標記和清除,減少停頓時間。
- 算法:基于標記-清除。
- 優(yōu)點:適合對延遲敏感的應用(如 Web 服務(wù))。
- 缺點:會產(chǎn)生內(nèi)存碎片,吞吐量低于 Parallel GC;在 JDK 9 起被標記為廢棄。
4. G1(Garbage-First)
- 特點:目前主流,JDK 9 之后默認收集器。
- 設(shè)計:堆被劃分為多個 Region,每次優(yōu)先回收垃圾最多的 Region。
- 優(yōu)點:兼顧吞吐量和低延遲,可預測停頓時間(如
-XX:MaxGCPauseMillis=200)。 - 算法:新生代 → 復制;老年代 → 標記-整理。
5. 其他新一代收集器
- ZGC(JDK 11+):超低延遲,GC 停頓 < 10ms,支持 TB 級堆。
- Shenandoah(JDK 12+):與 ZGC 類似,低延遲 GC。
總結(jié)
- 新生代:復制算法(快速回收,大部分對象很快死亡)。
- 老年代:標記-整理(減少碎片,適合長期對象)。
常見收集器:
- 小應用:Serial GC
- 吞吐量優(yōu)先:Parallel GC
- 低延遲:CMS(逐漸淘汰)、G1(主流)
- 超大堆/超低延遲:ZGC、Shenandoah
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
IDEA創(chuàng)建Servlet并配置web.xml的實現(xiàn)
這篇文章主要介紹了IDEA創(chuàng)建Servlet并配置web.xml的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-10-10
Spring?Boot?整合RocketMq實現(xiàn)消息過濾功能
這篇文章主要介紹了Spring?Boot?整合RocketMq實現(xiàn)消息過濾,本文講解了RocketMQ實現(xiàn)消息過濾,針對不同的業(yè)務(wù)場景選擇合適的方案即可,需要的朋友可以參考下2022-06-06
Spring Boot部署到Tomcat過程中遇到的問題匯總
這篇文章主要給大家分享了關(guān)于Spring Boot部署到Tomcat過程中遇到的一些問題,文中將解決的方法介紹非常詳細,對同樣遇到這個問題的朋友具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。2018-03-03
Spring框架應用的權(quán)限控制系統(tǒng)詳解
在本篇文章里小編給大家整理的是關(guān)于基于Spring框架應用的權(quán)限控制系統(tǒng)的研究和實現(xiàn),需要的朋友們可以學習下。2019-08-08
Java中的NumberFormatException異常原因以及解決方案詳解
這篇文章主要介紹了Java中的NumberFormatException異常原因以及解決方案詳解,NumberFormatException 是 Java 中的一個異常類,通常在字符串轉(zhuǎn)換為數(shù)字的過程中發(fā)生,它表示一個無效的數(shù)字格式,即字符串無法被正確解析為數(shù)字,需要的朋友可以參考下2024-02-02

