我们在Java中的一个object对象在jvm内存中占用的空间大小是多少呢?
  代码如下:
Object o = new Object() ;
这句代码执行时:
首先在该代码执行时,是在一个方法内,方法的数据存在于栈帧。在栈中,拿出一块空间,存放指向对象的指针的 o ,在堆中,new 出一个object对象,然后栈中的 o 指向堆中的对象。内存布局如图所示:
  

   那么,我们new出来的堆中的对象,具体的内存布局是什么样的呢。我们通过使用一个openjdk的类,将该对象的相关信息打印出来。
引入 Java Object Layout
新建一个maven 项目,配置 xml 文件如下:
<dependencies>
    <dependency>
        <groupId>org.openjdk.jol</groupId>
        <artifactId>jol-core</artifactId>
        <version>0.9</version>
    </dependency>

</dependencies>        
   测试代码如下:
  
1    publicstaticvoidmain(String[]args){
2        Objecto=newObject();
3        System.out.println(ClassLayout.parseInstance(o).toPrintable());
4    }
   输出结果为:
   java.lang.Object object internals:
   OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
     12     4        (loss due to the next object alignment)
   Instance size: 16 bytes
   Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
  输出的 java.lang.Object 对象的内存布局的解释
第一行 开始位置为0,大小为4个字节 type Description 里面内容的描述 ,这里装的是对象的头信息
第二行 从第4个字节开始,还是4个字节的大小,内容也还是对象头
第三行 第8个字节开始,还是4个字节,类型指针内容
第四行 第12个字节开始,4个字节,补全对齐的

 

 

 


普通对象内存信息
普通对象的内存信息由4部分组成,
  第一部分 markword 记录关于锁的信息,synchronized的所有信心都记录在这里。8个字节
  第二部分为类型指针,指向当前对象所属的class,用于标识对象到底属于哪个类,指向类的clazz内存地址。4个字节(开启类指针压缩的情况,不开启的话,是8个字节)
  第三部分为对象里面的成员变量所占的空间。(开启普通对象指针压缩 ooPs 后,该部分指针长度为4字节;不开启,指针长度为8字节。)
  第四部分为对齐,当对象整体字节数不能被8整除的时候将对象补成能被8整除的大小。
因为cpu在读内存里面值的时候,按照总线宽度读取,如果可以被8整除,那么会提高读取效率。

  类指针压缩 UseCompressedClassPointers
如果没有开启 UseCompressedClassPointers 类指针压缩64位的虚拟机,一个指针的长度是64位,也就是说8个字节。如果开启了UseCompressedClassPointers(操作系统默认开启)类型指针(class pointer)长度就是4个字节。
  普通对象指针压缩  UseCompressedOops
UseCompressedOops:普通对象指针压缩,oops: ordinary object pointer 成员变量指针的指向是否被进行压缩,也是默认开启,而且如果只开启类指针压缩,不开启普通对象指针压缩那么系统是会报错的
  结论:object对象,在内存中的堆中,无论是否开始指针压缩,都是16个字节。因为不压缩的话,对齐的4个字节就不存在了。在堆+栈中,如果开启指针压缩的话,那么是20个字节,没有开启的话是24个字节。

posted on 2020-06-29 17:16  精品唯居  阅读(584)  评论(0编辑  收藏  举报