对于G1和CMS,UseCompressedOops启动阈值不同

时间:2016-08-03 20:12:20

标签: java garbage-collection g1gc concurrent-mark-sweep

我正在运行Oracle的64位Java 1.8 Hotspot JVM。当我使用不同的GC机制时,我一直试图围绕JVM的行为差异来启动压缩对象指针。例如:

$ java -XX:+UseConcMarkSweepGC -XX:+PrintFlagsFinal -Xms32766m -Xmx32766m

bool UseCompressedClassPointers        := true        {lp64_product}
bool UseCompressedOops                 := true        {lp64_product}

$ java -XX:+UseConcMarkSweepGC -XX:+PrintFlagsFinal -Xms32767m -Xmx32767m

bool UseCompressedClassPointers        = false        {lp64_product}
bool UseCompressedOops                 = false        {lp64_product}

$ java -XX:+UseG1GC -XX:+PrintFlagsFinal -Xms32736m -Xmx32736m

bool UseCompressedClassPointers        := true        {lp64_product}
bool UseCompressedOops                 := true        {lp64_product}

$ java -XX:+UseG1GC -XX:+PrintFlagsFinal -Xms32737m -Xmx32737m

bool UseCompressedClassPointers        = false        {lp64_product}
bool UseCompressedOops                 = false        {lp64_product}

我已经尝试更改其他一些G1GC旋钮,但无法获得压缩指针优化,以便为G1的堆大小超过32736 MB。但是,正如您可以清楚地看到CMS可以使用压缩指针的堆大小高达32766 MB。我试图理解什么控制不同GC算法的阈值。

1 个答案:

答案 0 :(得分:1)

  

但无法获得压缩指针优化,以便在堆大小超过32736 MB的情况下启动

这是正常的,因为默认情况下对象与8字节边界对齐,这意味着最低的3位是冗余的并且通过移位来消除,这反过来意味着32位对象指针最多可以通过该对齐来处理4GB * 8的对象

如果要使用压缩oops超过32GB,则需要通过-XX:ObjectAlignmentInBytes=16将对象对齐到16个字节。请注意,这会使较小的对象变大,即浪费一些内存,因此您必须衡量它是否真正获得了任何东西。

This answer有一些可能感兴趣的其他诊断选项。