Xmx 和 MaxRAM JVM 參數之間的差異
1. 概述
堆大小是Java應用程式的重要參數。它直接影響我們可以使用多少內存,並間接影響應用程式的效能。例如,壓縮指針的使用、垃圾收集週期的數量和持續時間等。
在本教程中,我們將學習如何使用XX:MaxRAM
標誌為堆疊大小計算提供更多調整機會。當在容器內或不同主機上執行應用程式時,這一點尤其重要。
2. 堆疊大小計算
用於配置堆的標誌可以一起工作,也可以相互覆蓋。了解他們的關係對於更深入地了解他們的目的很重要。
2.1.使用-Xmx
控制堆大小的主要方法是-Xmx
和-Xms
標誌,它們分別控制最大和初始大小。它是一個強大的工具,但不考慮機器或容器上的可用空間。假設我們在可用 RAM 範圍從 4 GB 到 64 GB 的各種主機上執行應用程式。
如果沒有-Xmx,
JVM 會自動為應用程式堆分配大約 25% 的可用 RAM。然而,一般來說,JVM 分配的初始堆大小取決於各種參數:系統架構、JVM 版本、平台等。
在某些情況下,這種行為可能是不受歡迎的。根據可用的 RAM,它可能會分配截然不同的堆。讓我們檢查一下 JVM 在 24 GB RAM 的機器上預設分配了多少記憶體:
$ java -XX:+PrintFlagsFinal -version |\
grep -e '\bMaxHeapSize\|\bMinHeapSize\|\bInitialHeapSize'
size_t InitialHeapSize = 402653184 {product} {ergonomic}
size_t MaxHeapSize = 6442450944 {product} {ergonomic}
size_t MinHeapSize = 8388608 {product} {ergonomic}
JVM 分配了大約 6 GB 或 25%,這對我們的應用程式來說可能太多了。將最大堆設為特定值也可能產生問題。如果我們使用-Xmx4g,
對於可用記憶體少於的主機,它可能會失敗,而且,我們不會獲得可以擁有的額外記憶體:
$ java -XX:+PrintFlagsFinal -Xmx4g -version |\
grep -e '\bMaxHeapSize\|\bMinHeapSize\|\bInitialHeapSize'
size_t InitialHeapSize = 402653184 {product} {ergonomic}
size_t MaxHeapSize = 4294967296 {product} {command line}
size_t MinHeapSize = 8388608 {product} {ergonomic}
在某些情況下,可以透過使用腳本動態計算-Xmx
來解決此問題。但是,它繞過了可能更準確地了解應用程式需求的 JVM 啟發式方法。
2.2.使用-XX:MaxRAM
-XX:MaxRAM
標誌旨在解決上述問題。首先,它可以防止 JVM 在具有大量 RAM 的系統上過度分配記憶體。我們可以將此標誌視為“運行應用程序,但假設您最多有 X 數量的 RAM”。
此外, -XX:MaxRAM
允許 JVM 對堆疊大小使用標準啟發式。讓我們回顧一下前面的範例,但使用-XX:MaxRAM
:
$ java -XX:+PrintFlagsFinal -XX:MaxRAM=6g -version |\
grep -e '\bMaxHeapSize\|\bMinHeapSize\|\bInitialHeapSize'
size_t InitialHeapSize = 100663296 {product} {ergonomic}
size_t MaxHeapSize = 1610612736 {product} {ergonomic}
size_t MinHeapSize = 8388608 {product} {ergonomic}
在這種情況下,JVM 會計算最大堆大小,但假設我們只有 6 GB RAM。請注意,我們不應將-Xmx
與-XX:MaxRAM
使用。因為-Xmx
更具體,所以它會覆蓋-XX:MaxRAM
:
$ java -XX:+PrintFlagsFinal -XX:MaxRAM=6g -Xmx6g -version |\
grep -e '\bMaxHeapSize\|\bMinHeapSize\|\bInitialHeapSize'
size_t InitialHeapSize = 100663296 {product} {ergonomic}
size_t MaxHeapSize = 6442450944 {product} {command line}
size_t MinHeapSize = 8388608 {product} {ergonomic}
此標誌可以提高資源利用率和堆分配。但是,我們仍然無法控制應將多少 RAM 分配給堆。
2.3.使用-XX:MaxRAMPercentage
和-XX:MinRAMPercentage
現在我們處於控制之中,可以告訴 JVM 它應該考慮多少 RAM。讓我們定義分配堆的策略。 -XX:MaxRAM
標誌與-XX:MaxRAMPercentage
和-XX:MinRAMPercentage.
它們提供了更大的靈活性,特別是在容器化環境中。讓我們嘗試將其與-XX:MaxRAM
一起使用,並將堆設置為可用 RAM 的 50%:
$ java -XX:+PrintFlagsFinal -XX:MaxRAM=6g -XX:MaxRAMPercentage=50 -version |\
grep -e '\bMaxHeapSize\|\bMinHeapSize\|\bInitialHeapSize'
size_t InitialHeapSize = 100663296 {product} {ergonomic}
size_t MaxHeapSize = 3221225472 {product} {ergonomic}
size_t MinHeapSize = 8388608 {product} {ergonomic}
關於-XX:MinRAMPercentage
有一個常見的混淆。它的行為與-Xms.
儘管如此,可以合理地假設它設定了最小堆大小。讓我們檢查以下設定:
$ java -XX:+PrintFlagsFinal -XX:MaxRAM=16g -XX:MaxRAMPercentage=10 -XX:MinRAMPercentage=50 -version |\
grep -e '\bMaxHeapSize\|\bMinHeapSize\|\bInitialHeapSize'
size_t InitialHeapSize = 268435456 {product} {ergonomic}
size_t MaxHeapSize = 1719664640 {product} {ergonomic}
size_t MinHeapSize = 8388608 {product} {ergonomic}
我們設定了-XX:MaxRAMPercentage
和-XX:MinRAMPercentage
,但很明顯只有-XX:MaxRAMPercentage
起作用。我們將 16 GB RAM 的 10% 分配給堆。但是,如果我們將可用 RAM 減少到 200 MB,我們會得到不同的行為:
$ java -XX:+PrintFlagsFinal -XX:MaxRAM=200m -XX:MaxRAMPercentage=10 -XX:MinRAMPercentage=50 -version |\
grep -e '\bMaxHeapSize\|\bMinHeapSize\|\bInitialHeapSize'
size_t InitialHeapSize = 8388608 {product} {ergonomic}
size_t MaxHeapSize = 109051904 {product} {ergonomic}
size_t MinHeapSize = 8388608 {product} {ergonomic}
在這種情況下,堆大小由-XX:MinRAMPercentage
控制。當可用 RAM 降至低於 200 MB 時,此標誌就會啟動。現在,我們可以將堆增加到 75%:
$ java -XX:+PrintFlagsFinal -XX:MaxRAM=200m -XX:MaxRAMPercentage=10 -XX:MinRAMPercentage=75 -version |\
grep -e '\bMaxHeapSize\|\bMinHeapSize\|\bInitialHeapSize'
size_t InitialHeapSize = 8388608 {product} {ergonomic}
size_t MaxHeapSize = 134217728 {product} {ergonomic}
size_t MinHeapSize = 8388608 {product} {ergonomic}
如果我們繼續對如此小的堆應用-XX:MaxRAMPercentage
,我們將獲得 20 MB 的堆,這可能不足以滿足我們的目的。這就是為什麼我們對小堆和大堆有不同的標誌。 -XX:MaxRAM
標誌與它們都可以很好地配合,並為我們提供更多控制。
三、結論
控制堆大小對於 Java 應用程式至關重要。分配更多記憶體不一定是好事;同時,分配不足的記憶體也是不好的。
使用-Xmx, -XX:MaxRAM, -XX:MaxRAMPercentage,
和-XX:MinRAMPercentage
可以幫助我們更好地調整應用程式並提高效能。