我想知道是否有某种方法让64位VM使用8byte对象头而不是12byte对象头,如果JVM的可用RAM仍然是4GB。
或者就像在Linux上那样,如果没有在Windows上?有人可以用这段代码测试吗?
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.");
}
}
答案 0 :(得分:16)
在64位JVM上看起来不可能有一个8字节的对象头。标题由“标记字”,指向对象类的指针,数组中的数组大小以及到达下一个8字节边界的填充组成。
,------------------+------------------+------------------ +---------------.
| mark word | klass pointer | array size (opt) | padding |
`------------------+------------------+-------------------+---------------'
因此,64位系统上的对象标头可以占用8 + 4 = 12字节,但不能少。
答案 1 :(得分:3)
对于64位虚拟机,有以下选项:
在这种情况下:对象头将是12个字节,数组头将是16个字节(对于数组大小,最后4个字节)
2.未通过-XX使用压缩指针:-UseCompressedOops
在这种情况下:对象头将是16个字节,数组头将是20个字节(对于数组大小,最后4个字节)
上面给出的代码不是VM位大小独立的,并且将为32位和64位vms提供不同的结果。您需要考虑位和压缩的oops因子来计算正确的大小。
答案 2 :(得分:-1)
通过-XX使用压缩指针:+ UseCompressedOops(在Java 6上默认启用)
对于所有版本的Java 6都不是这样。默认情况下启用-XX:+UseCompressedOops
从Java 6u25开始