64位虚拟机上的Java对象头大小,带<;4GB内存
我想知道,如果JVM的可用RAM为4GB,是否有办法让64位VM使用8字节的对象头而不是12字节的对象头 如果不是在windows上,它在Linux上也是这样吗?有人能用这个代码测试一下吗64位虚拟机上的Java对象头大小,带<;4GB内存,java,linux,windows,64-bit,Java,Linux,Windows,64 Bit,我想知道,如果JVM的可用RAM为4GB,是否有办法让64位VM使用8字节的对象头而不是12字节的对象头 如果不是在windows上,它在Linux上也是这样吗?有人能用这个代码测试一下吗 import java.lang.reflect.Field; import sun.misc.Unsafe; public class ObjectSizes { String s1; String s2; public static void main(String[] args)
import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class ObjectSizes {
String s1;
String s2;
public static void main(String[] args) throws Exception {
Unsafe unsafe;
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe)field.get(null);
} catch (Exception ex) {
throw new RuntimeException("Can't get Unsafe instance.", ex);
}
Field s1Field = ObjectSizes.class.getDeclaredField("s1");
Field s2Field = ObjectSizes.class.getDeclaredField("s2");
long s1OffSet = unsafe.objectFieldOffset(s1Field);
long s2OffSet = unsafe.objectFieldOffset(s2Field);
System.out.println("We are running "+System.getProperty("java.version"));
System.out.println("Object header size is "+s1OffSet+" bytes.");
System.out.println("Object reference size is "+(s2OffSet-s1OffSet)+" bytes.");
}
}
在64位JVM上看起来不可能有8字节的对象头。标头由一个“标记字”、一个指向对象类的指针、数组大小(如果是数组)以及填充到下一个8字节边界的内容组成
,------------------+------------------+------------------ +---------------.
| mark word | klass pointer | array size (opt) | padding |
`------------------+------------------+-------------------+---------------'
- 标记字可用于存储本机指针,因此它在64位JVM上占用8个字节
- 当堆小于32GB时,指向对象类的指针
- 填充可用于存储其中一个字段
因此,64位系统上的对象标头最多可以占用8+4=12字节,但不能少于。对于64位虚拟机,有以下选项:
并非所有版本的Java6都是如此<代码>-XX:+UseCompressedOops默认启用,从Java 6u25开始当您参考@NitinS answer时,您可以使用注释而不是发布答案。