UseCompressedClassPointers和UseCompressedOops

67 阅读2分钟

UseCompressedClassPointers和UseCompressedOops都是JVM对指针进行压缩的设置,比较一下两个参数的适用范围,下面使用openjdk的jol-core打印一下

1、maven引入

<dependency>
  <groupId>org.openjdk.jol</groupId>
  <artifactId>jol-core</artifactId>
  <version>0.16</version>
</dependency>

2、代码

package cn.callmebuzhou.jvm;
import org.openjdk.jol.info.ClassLayout;
public class CompressedCommandTest {
    public static void main(String[] args) {
        System.out.println(ClassLayout.parseInstance(new T()).toPrintable());
    }
    static class T{
        String name;
    }
}

3、开始测试

首先要明确一个,默认情况下两个都会默认开启压缩

3.1、默认情况下什么参数都不加

image.png

运行结果:

cn.callmebuzhou.jvm.CompressedCommandTest$T object internals:
OFF  SZ               TYPE DESCRIPTION               VALUE
  0   8                    (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   4                    (object header: class)    0xf800c043
 12   4   java.lang.String T.name                    null
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

可以看到第四行类类型指针占4字节,第五行对象引用指针也是4字节,说明都进行了压缩

3.2、关闭UseCompressedClassPointers

-XX:-UseCompressedClassPointers

image.png

运行结果

cn.callmebuzhou.jvm.CompressedCommandTest$T object internals:
OFF  SZ               TYPE DESCRIPTION               VALUE
  0   8                    (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   8                    (object header: class)    0x00000205ce5608d0
 16   4   java.lang.String T.name                    null
 20   4                    (object alignment gap)    
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

打印结果可以看出来,这里类类型指针没有压缩,占8字节,对象引用指针占4字节压缩了

3.3、开启UseCompressedClassPointers

-XX:+UseCompressedClassPointers

image.png

运行结果

cn.callmebuzhou.jvm.CompressedCommandTest$T object internals:
OFF  SZ               TYPE DESCRIPTION               VALUE
  0   8                    (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   8                    (object header: class)    0x00000205717908d0
 16   4   java.lang.String T.name                    null
 20   4                    (object alignment gap)    
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

运行结果是类类型指针不做压缩,对象引用指针压缩了

3.3、关闭UseCompressedOops

-XX:-UseCompressedOops

image.png

运行结果

cn.callmebuzhou.jvm.CompressedCommandTest$T object internals:
OFF  SZ               TYPE DESCRIPTION               VALUE
  0   8                    (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   8                    (object header: class)    0x0000013d53e708d0
 16   8   java.lang.String T.name                    null
Instance size: 24 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

可以看出来,类类型指针和对象引用指针都未进行了压缩

3.4、开启UseCompressedOops

-XX:+UseCompressedOops

image.png

运行结果

cn.callmebuzhou.jvm.CompressedCommandTest$T object internals:
OFF  SZ               TYPE DESCRIPTION               VALUE
  0   8                    (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   4                    (object header: class)    0xf800c043
 12   4   java.lang.String T.name                    null
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

可以看出来,类类型指针和对象引用指针进行了压缩,这里有人会说,也许是UseCompressedClassPointers默认值起了效果,那我们继续往下看

3.5、关闭UseCompressedClassPointers && 开启UseCompressedOops

-XX:-UseCompressedClassPointers -XX:+UseCompressedOops

image.png

运行结果

cn.callmebuzhou.jvm.CompressedCommandTest$T object internals:
OFF  SZ               TYPE DESCRIPTION               VALUE
  0   8                    (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   8                    (object header: class)    0x000001ae2de408d0
 16   4   java.lang.String T.name                    null
 20   4                    (object alignment gap)    
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

这下就很明细了,如果开启UseCompressedOops类类型指针和对象引用指针都会做压缩,如果想类类型指针不进行压缩需要显式设置

3.6、开启UseCompressedClassPointers && 关闭UseCompressedOops

-XX:+UseCompressedClassPointers -XX:-UseCompressedOops

image.png

Java HotSpot(TM) 64-Bit Server VM warning: UseCompressedClassPointers requires UseCompressedOops
cn.callmebuzhou.jvm.CompressedCommandTest$T object internals:
OFF  SZ               TYPE DESCRIPTION               VALUE
  0   8                    (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   8                    (object header: class)    0x00000154fc5508d0
 16   8   java.lang.String T.name                    null
Instance size: 24 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

Java HotSpot(TM) 64-Bit Server VM warning: UseCompressedClassPointers requires UseCompressedOops

参数类型类类型指针引用类型指针
默认情况压缩压缩
关闭UseCompressedClassPointers未压缩压缩
开启UseCompressedClassPointers压缩压缩
关闭UseCompressedOops未压缩未压缩
开启UseCompressedOops压缩压缩
关闭UseCompressedClassPointers && 开启UseCompressedOops未压缩压缩
开启UseCompressedClassPointers && 关闭UseCompressedOops未压缩未压缩