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

JVM 垃圾收集深度解析(二):自適應收集、火車算法與 finalize 陷阱

     編輯:Java 相關知識

自適應垃圾收集

JVM 啟動後不固定使用單一演算法,而是根據堆運行狀況動態調整:切換演算法、調整參數、劃分子堆並對不同代使用不同策略。目標是針對不同對象壽命特徵選擇最優收集方式。

漸進式收集與非破壞性目標

傳統 GC 會暫停整個應用(Stop-the-world),導致不可預測的延遲。漸進式收集器每次只處理堆的一部分,理論上單次暫停時間更短。若能將最大暫停時間控制在固定閾值內,即可滿足實時系統需求,稱為「限時漸進式垃圾收集」。

分代收集與火車算法

分代假設

  • 大多數對象朝生夕死(短命)。
  • 長壽對象極少,移動成本高。

因此將堆劃分為年輕代(頻繁收集)與老年代(較少收集)。對象經過多次 GC 存活即晉升到老年代。

火車算法

針對老年代無法預知大小的問題,Richard Hudson 與 Eliot Moss 提出火車算法(Train Algorithm),現用於 HotSpot VM。概念:

  • 老年代劃分為多個「車廂」,車廂組成「火車」。
  • 每次收集一節車廂,將存活對象移動到後方車廂或新火車。
  • 最前方火車的車廂若無外部引用,整列車可回收。

此法實現老年代的限時漸進式收集,避免全堆掃描帶來的長暫停。

finalize() 方法的代價

雖然 finalize() 允許對象在回收前執行清理,但引入後 GC 流程變複雜:

  1. 第一遍掃描發現不可觸及對象,若有 finalize() 則放入最終化隊列。
  2. 執行所有 finalize(),期間對象可能「復活」(被重新引用)。
  3. 第二遍掃描從根節點及最終化對象出發,再次判定存活。
  4. 最終回收兩次掃描均未存活的對象。

缺點: 執行時機不可預測、可能延遲回收、復活後 finalize() 不再執行、增加 GC 負擔。建議: 能不用就不用,改用 PhantomReference 或 try-with-resources。

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