Java:ヒープサイズはどのように決定されるのか?
一般に、Javaプログラムがメモリ不足に陥った場合には、VMに-Xmxフラグをつけて最大ヒープサイズを指定しろと言われるのだが、そもそもデフォルトの最大ヒープサイズはどのように決定されるのだろうか?以下に答えがあった。
これによると、一般的にはマシンの物理メモリの1/4か、あるいは1GBの小さい方だという。ということは、いくら物理メモリを積んでいても、1GBにしかならないということ(と解釈したが、テストしてみた限りでは1/4が採用されている)。
デフォルトの値を見るには、以下を実行する(Windowsの場合)
java -XX:+PrintFlagsFinal -version | findstr /i "HeapSize PermSize ThreadStackSize"
手元のAdoptOpenJDK12でやってみると以下になった。物理メモリは8GB。
C:\Users\admin>java -XX:+PrintFlagsFinal -version | findstr /i "HeapSize PermSiz
e ThreadStackSize"
intx CompilerThreadStackSize = 0
{pd product} {default}
size_t ErgoHeapSizeLimit = 0
{product} {default}
size_t HeapSizePerGCThread = 43620760
{product} {default}
size_t InitialHeapSize = 132120576
{product} {ergonomic}
size_t LargePageHeapSizeThreshold = 134217728
{product} {default}
size_t MaxHeapSize = 2111832064
{product} {ergonomic}
uintx NonNMethodCodeHeapSize = 5830732
{pd product} {ergonomic}
uintx NonProfiledCodeHeapSize = 122913754
{pd product} {ergonomic}
uintx ProfiledCodeHeapSize = 122913754
{pd product} {ergonomic}
intx ThreadStackSize = 0
{pd product} {default}
intx VMThreadStackSize = 0
{pd product} {default}
openjdk version "12.0.1" 2019-04-16
OpenJDK Runtime Environment AdoptOpenJDK (build 12.0.1+12)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 12.0.1+12, mixed mode, sharing)
ということで、MaxHeapSizeは2GBになっている。次に、-Xmxフラグをつけてみる。物理メモリをはるかに超える-Xmx16gを指定する。
C:\Users\admin>java -Xmx16g -XX:+PrintFlagsFinal -version | findstr /i "HeapSize
PermSize ThreadStackSize"
intx CompilerThreadStackSize = 0
{pd product} {default}
size_t ErgoHeapSizeLimit = 0
{product} {default}
size_t HeapSizePerGCThread = 43620760
{product} {default}
size_t InitialHeapSize = 134217728
{product} {ergonomic}
size_t LargePageHeapSizeThreshold = 134217728
{product} {default}
size_t MaxHeapSize = 17179869184
{product} {command line}
uintx NonNMethodCodeHeapSize = 5830732
{pd product} {ergonomic}
uintx NonProfiledCodeHeapSize = 122913754
{pd product} {ergonomic}
uintx ProfiledCodeHeapSize = 122913754
{pd product} {ergonomic}
intx ThreadStackSize = 0
{pd product} {default}
intx VMThreadStackSize = 0
{pd product} {default}
openjdk version "12.0.1" 2019-04-16
OpenJDK Runtime Environment AdoptOpenJDK (build 12.0.1+12)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 12.0.1+12, mixed mode, sharing)
たしかに、16G(実際には17GB)と表示されている。