美文网首页内存对象基础知识
Java对象在内存中的结构分析

Java对象在内存中的结构分析

作者: abc_wangyu | 来源:发表于2017-08-01 15:00 被阅读26次

    问题:在Hotspot JVM中,32位机器下,Integer对象的大小是int的几倍?

    HotSpot虚拟机中,对象在内存中的布局分为三块区域:对象头、实例数据和对齐填充,其中对象头又分为:Mark World和Class Pointer,如下图:


    对象内存结构

    从上面的这张图里面可以看出,对象在内存中的结构主要包含以下几个部分:

    1) Mark Word:对象的Mark Word部分占4个字节,其内容是一系列的标记位,比如轻量级锁的标记位,偏向锁标记位等等(32位)。

    2) Class对象指针:Class对象指针的大小也是4个字节,其指向的位置是对象对应的Class对象(其对应的元数据对象)的内存地址(32位)。

    3) 对象实际数据:这里面包括了对象的所有成员变量,其大小由各个成员变量的大小决定,比如:byte和boolean是1个字节,short和char是2个字节,int和float是4个字节,long和double是8个字节,reference是4个字节(32位)。

    4) 对齐:最后一部分是对齐填充的字节,按8个字节填充(32位)。

    PS:关于对象的内存结构,需要注意数组的内存结构和普通对象的内存结构稍微不同,因为数组有一个长度length字段,所以在对象头后面还多了一个int类型的length字段,占4个字节。

    Integer有一个int类型的成员变量value,所以其对象实际数据部分的大小是4个字节,然后再在后面填充4个字节达到8字节的对齐,所以可以得出Integer对象的大小是16个字节。因此,我们可以得出Integer对象的大小(最小)是原生的int类型的4倍。


    Mark World

    用于存储对象自身的运行时数据, 如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等等,这部分数据的长度在32位和64位的虚拟机(暂不考虑开启压缩指针的场景)中分别为32bit和64bit,官方称它为“Mark Word”。Mark Word被设计成一个非固定的数据结构以便在极小的空间内存储尽量多的信息,它会根据对象的状态复用自己的存储空间。

    例如在32位的HotSpot虚拟机中对象未被锁定的状态下(无锁态),Mark Word的32个bit空间中的25bit用于存储对象哈希码,4bit用于存储对象分代年龄,2bit用于存储锁标志位,1bit固定为0,在其他状态(轻量级锁定、重量级锁定、GC标记、可偏向)下对象的存储内容如下表所示。


    关于Mark World,参考小狼:http://www.jianshu.com/p/9c19eb0ea4d8

    锁状态

    锁的状态总共有四种:无锁状态、偏向锁、轻量级锁和重量级锁。随着锁的竞争,锁可以从偏向锁升级到轻量级锁,再升级的重量级锁(但是锁的升级是单向的,也就是说只能从低到高升级,不会出现锁的降级)。JDK 1.6中默认是开启偏向锁和轻量级锁的,我们也可以通过-XX:-UseBiasedLocking来禁用偏向锁。关于JVM锁优化:http://www.jianshu.com/p/2d72c6bab241

    相关文章

      网友评论

        本文标题:Java对象在内存中的结构分析

        本文链接:https://www.haomeiwen.com/subject/fapjlxtx.html