Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
64位虚拟机上的Java对象头大小,带<;4GB内存_Java_Linux_Windows_64 Bit - Fatal编程技术网

64位虚拟机上的Java对象头大小,带<;4GB内存

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)

我想知道,如果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) 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位虚拟机,有以下选项:

  • 通过-XX:+UseCompressedOops使用压缩指针(在Java6上默认启用)
  • 在这种情况下:对象头将是12个字节,数组头将是16个字节(最后4个字节表示数组大小)

    2.不通过-XX:-UseCompressedOops使用压缩指针

    在这种情况下:对象头将是16个字节,数组头将是20个字节(最后4个字节表示数组大小)

    上面给出的代码不是与VM位大小无关的,它将为32位和64位VM提供不同的结果。你需要考虑比特度和压缩OOPS因子来计算正确的大小。 通过-XX:+UseCompressedOops使用压缩指针(在Java6上默认启用)


    并非所有版本的Java6都是如此<代码>-XX:+UseCompressedOops默认启用,从Java 6u25开始

    当您参考@NitinS answer时,您可以使用注释而不是发布答案。