簡體   English   中英

MaxTenuringThreshold - 它究竟是如何工作的?

[英]MaxTenuringThreshold - how exactly it works?

我們知道很少有主內存域:Young、Tenured(老一代)和 PermGen。

  • Young域分為Eden和Survivor(有兩種)。
  • OldGen 用於幸存的對象。

MaxTenuringThreshold 可防止對象過早地最終復制到 OldGen 空間。 這是非常清楚和易於理解的。

但它是如何工作的? 垃圾收集器如何處理這些在 MaxTenuringThreshold 之前仍然存活的對象?以什么方式? 它們位於何處?

對象正在被復制回 Survivor 空間進行垃圾收集......還是以其他方式發生?

Java 堆中的每個對象都有一個由垃圾收集 (GC) 算法使用的標頭。 年輕空間收集器(負責對象提升)使用此標頭中的一些位來跟蹤幸存的集合對象的數量(32 位 JVM 為此使用 4 位,64 位可能更多) .

在年輕空間收集期間,每個對象都被復制。 對象可以復制到生存空間之一(在年輕 GC 之前為空的空間)或舊空間。 對於每個被復制的對象,GC 算法會增加它的年齡(存活的集合數量),如果年齡高於當前的任期閾值,它將被復制(提升)到舊空間。 如果生存空間已滿(溢出),也可以將對象直接復制到舊空間。

Object 的旅程具有以下模式:

  • 分配在伊甸園
  • 由於年輕 GC 從伊甸園復制到生存空間
  • 由於年輕的 GC 從生存空間復制到(其他)生存空間(這可能發生幾次)
  • 由於年輕GC(或完整GC),從生存(或可能的伊甸園)提升到舊空間

實際的任期閾值由 JVM 動態調整,但 MaxTenuringThreshold 對其設置了上限。

如果設置 MaxTenuringThreshold=0,則所有對象將立即提升。

我有幾篇關於java垃圾收集的文章,你可以在那里找到更多細節。

(免責聲明:這僅涵蓋 HotSpot VM)

正如 Alexey 所說,實際使用的任期閾值是由 JVM 動態確定的。 設置它的價值很小。 對於大多數應用程序,默認值 15 已經足夠高了,因為通常會有更多的對象在集合中存活下來。 當許多對象在集合中幸存下來時,幸存者空間直接溢出到舊的。 這稱為過早提升和問題的指標。 然而,它很少可以通過調整 MaxTenuringThreshold 來解決。

在這些情況下,有時可能會使用 SurvivorRatio 來增加幸存者空間中的空間,從而使任期真正起作用。 然而,通常擴大年輕代是唯一好的選擇(從配置的角度來看)。 如果您是從編碼的角度來看,您應該避免過多的對象分配,讓任期按設計工作。

准確回答您的問題:當一個對象達到其 JVM 確定的任期閾值時,它會被復制到舊的。 在此之前,它將被復制到空的幸存者空間。 已經存活一段時間但在達到閾值之前被取消引用的對象會非常有效地從幸存者中清除。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM