首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 內存管理與垃圾回收核心原理:從對象存活判定到 GC 算法演進

     編輯:Java 綜合教學

前言

Java 自動內存管理機制釋放了開發者手動釋放內存的負擔,但也帶來了「不可控」的困惑。本文系統梳理 JVM 運行時區域、對象死亡判定算法、主流 GC 策略,幫助建立完整的內存管理知識體系。

一、JVM 運行時區域速覽

JVM 運行時區域圖

  • 程序計數器:線程私有,字節碼行號指示器,用於線程切換恢復。
  • 虛擬機棧:線程私有,方法調用棧幀,存局部變量表(基本類型、對象引用)。
  • 本地方法棧:服務 Native 方法。
  • 堆:線程共享,對象實例主存儲區,GC 主戰場。
  • 方法區:線程共享,存類信息、常量、靜態變量、JIT 代碼,含運行時常量池。

二、對象已死?—— 存活判定算法

GC 核心任務:找出不可達對象並回收。

1. 引用計數法

給對象添加引用計數器,引用+1,釋放-1,計數為 0 即可回收。

缺陷:無法解決循環引用問題。
ObjA.instance = ObjB; ObjB.instance = ObjA;
兩對象互相引用計數不為 0,但實際已不可達。

2. 可達性分析法

主流 JVM 採用。以「GC Roots」為起點,向下搜索引用鏈,能到達的對象存活,不可達則判死。

可達性分析示意圖

GC Roots 包含:

  • 虛擬機棧中引用的對象(局部變量表)
  • 方法區中類靜態屬性引用的對象
  • 方法區中常量引用的對象
  • 本地方法棧中 JNI 引用的對象

三、垃圾回收策略(三大經典算法)

1. 標記-清除

  • 過程:標記不可達對象 → 直接清除。
  • 缺點:效率低(兩次掃描);產生大量內存碎片,導致大對象分配困難。

2. 複製算法

  • 過程:內存劃分為等大 A、B 兩塊,每次用一塊。GC 時將存活對象複製到另一塊,然後清空已用塊。
  • 缺點:內存利用率只有 50%,代價太大。
  • 改進(新生代實踐):按 8:1:1 劃分 Eden、From、To。GC 時將 Eden+From 存活對象複製到 To,清空 Eden+From,角色互換。利用率達 90%。

3. 標記-整理

  • 過程:標記後,將所有存活對象向一端移動,然後清理邊界外內存。
  • 適用:老年代(存活率高,複製代價大),解決碎片問題。

四、參考資源

  1. 百度經驗:Java垃圾回收機制詳解
  2. 強烈推薦:Vamei - JVM垃圾回收原理
  3. 《深入理解Java虛擬機:JVM高級特性與最佳實踐》—— 周志明

總結

理解內存管理從「對象怎麼死」到「怎麼回收」的演進,是 Java 工程師進階的關鍵。可達性分析解決了引用計數的循環引用缺陷;分代收集理論建立在「弱分代假說」之上,新生代用複製,老年代用標記-整理。掌握這些原理,才能看懂 GC 日誌、調優堆參數、排查 OOM 與內存洩漏。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved