我们在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个字节。
文章来源:http://www.cnblogs.com/liyasong/