JDK8垃圾回收調優指南--(4)設置代大小

原文:Java Platform, Standard Edition HotSpot Virtual Machine Garbage Collection Tuning Guide--Sizing the Generations

許多參數會影響代的大小。圖4-1說明了堆中提交空間和虛擬空間之間的差異。在虛擬機初始化時,爲堆保留了整個空間。
(堆)保留空間的大小可以使用'-Xmx'選項指定。如果'-Xms'參數的值小於'-Xmx'參數的值,則不是所有保留的空間都立即提交給虛擬機。圖中未提交的空間被標記爲“virtual”。堆的不同部分(年輕代和老年代)可以根據需要增長到虛擬空間的極限。

有些參數是堆的一部分與另一部分的比值。例如,參數'NewRatio'表示老年代相對於年輕代的大小。

Heap Parameters

Total Heap

下面關於堆的增長和收縮以及默認堆大小的討論不適用於並行收集器(有關使用並行收集器調整堆大小和默認堆大小的詳細信息,請參閱並行收集器部分)。然而,控制堆總大小和代大小的參數的確適用於並行收集器。

影響垃圾收集性能的最重要因素是最大可用內存。每當代被佔滿時就會觸發垃圾回收,所以吞吐量與可用內存的數量成反比。

默認,虛擬機在每次GC時增加或減少堆大小,以將每次GC後空閒空間和存活對象的比例保持在特定範圍內。該目標範圍由參數'-XX:MinHeapFreeRatio=<minimum>'和'-XX:MaxHeapFreeRatio=<maximum>'設置爲百分比,總大小以'-Xms<min>'爲下限,以'-Xmx<max>'爲上限。64位Solaris操作系統(SPARC Platform Edition)的默認參數如表4-1所示:

有了這些參數,如果代的空閒空間百分比低於40%,那麼這個代將被擴展,以保持40%的空閒空間,最高可達這個代允許的最大值。同樣,如果空閒空間百分比超過70%,那麼代將會被壓縮以滿足只有70%的空間是空閒的,以代的最小尺寸爲準(壓縮到最小值時,不會再壓縮)。

正如表4-1所示,默認堆最大值是由JVM計算的。Java SE中用於並行收集器和服務器JVM的(最大堆)計算現在用於所有垃圾收集器。計算的最大堆值對於32位平臺和64位平臺是不同的。參見並行收集器Default Heap Size部分。客戶機JVM也有類似的計算,(只是)它的最大堆值小於服務器JVM。

以下是關於服務器應用程序堆大小的一般準則:

  • 除非您對GC停頓有疑問,否則請嘗試將盡可能多的內存分配給虛擬機。默認堆值通常太小。
  • 將'-Xms'和'-Xmx'設置爲相同的值可以通過從虛擬機中移除最重要的sizing決策來提高可預測性。然而,如果您做出了錯誤的選擇,虛擬機將無法進行補償。
  • 通常,隨着處理器數量的增加而增加內存,因爲內存分配可以並行化。

The Young Generation

除了最大可用內存之外,影響垃圾收集性能的第二大因素是用於年輕代的堆的比例。年輕代(內存)越大,'minor collection'的頻率越低。然而,對於有限制的堆大小(比如Xms=Xmx),較大的年輕代意味着較小的老年代,這將增加'major collection'的頻率。最優選擇取決於應用程序分配的對象的生存期的分佈情況。

默認情況下,年輕代的大小由參數'NewRatio'控制。例如,設置'-XX:NewRatio=3'意味着年輕代和老年代的比例爲1:3。
換句話說,eden和survivor空間的總大小(即年輕代)是總堆大小的四分之一。

參數'NewSize'和'MaxNewSize'約束了年輕代的邊界值。將這些值設置爲相同的值可以固定年輕代大小,就像將'-Xms'和'-Xmx'設置爲相同的值將固定總堆大小一樣。這比參數'NewRatio'定義的整數倍地調優年輕代更有用,更細的粒度。

Survivor Space Sizing

您可以使用參數'SurvivorRatio'來調整Survivor空間的大小,但這通常對性能並不重要。例如,'-XX:SurvivorRatio=6'將eden和survivor空間的比例設置爲1:6。換句話說,每個survivor空間的大小將是eden的六分之一,因此survivor將是年輕代的八分之一(不是七分之一,因爲有兩個survivor空間)。

如果survivor空間太小,則複製回收將直接溢出到老年代。如果survivor的空間太大,他們將是無用的空(空間浪費)。
在每次垃圾收集時,虛擬機都會選擇一個閾值數字,就是一個對象在被提升到老年代之前可以被複制的次數。選擇這個閾值是爲了讓survivor的內存佔用控制在一半。命令行選項'-XX:+PrintTenuringDistribution'(不是在所有垃圾收集器上都可用)可用於顯示年輕代對象的閾值和年齡。它對於觀察應用程序的對象生命週期分佈也很有用。

表4-2提供了Solaris系統的默認值:

Default Parameter Values for Survivor Space Sizing

年輕代最大值可以通過總堆的最大值和'NewRatio'參數的值計算而來(MaxNewSize = Xmx * (1/1+NewRatio))。參數'MaxNewSize'默認值"not limited"意味着計算值不受'MaxNewSize'的限制,除非在命令行中指定'MaxNewSize'的值。

以下是服務應用的一般準則:

  • 首先確定你能提供給虛擬機最大堆值的大小。然後根據年輕代的大小繪製性能指標,以找到最佳設置。
  1. 注意,堆內存最大值應該始終小於機器上安裝的內存大小,以避免過多的頁面錯誤(page)和抖動(thrashing)。
  • 如果總堆值是固定的,那麼增加年輕代大小需要減少老年代大小。保持老年代足夠大,以便在任何給定的時間都能容納應用程序使用的所有存活數據,加上一定數量的閒置空間(10到20%或更多)。
  • 受上述對老年代的限制:
  1. 給年輕代分配足夠的內存。
  2. 隨着處理器數量的增加,增加年輕代的大小,因爲內存分配可以並行化。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章