Java.lang.Integer对象布局与额外开销疑问——基于JOL工具分析
解开Java Integer对象12字节额外开销的最后4字节之谜
这个问题问得太到位了——用JOL深挖JVM对象布局的时候,这种细节最容易让人卡壳!咱们结合HotSpot虚拟机的对象头结构来拆解,尤其是你看到的12字节开销,应该是开启了**压缩指针(UseCompressedOops)**的64位JVM场景(这是当前64位JVM的默认配置,所以对象头从16字节压缩到了12字节)。
先对应你观察到的12字节开销,拆解成HotSpot的标准对象头组成:
- 4字节:压缩后的类元数据指针(就是你说的「对象所属类的地址」,指向
java.lang.Integer的类元数据) - 4字节:Mark Word的低32位(也就是你提到的「用于垃圾回收」的部分,存储对象在GC分代中的年龄、锁状态标记、偏向锁标识等)
- 4字节:Mark Word的高32位——这就是你疑惑的剩余4字节!
那这部分到底存了什么?核心用途有这些:
- 优先存储对象的哈希码:虽然
Integer.hashCode()直接返回自身的int值(不是基于内存地址的哈希),但JVM还是会在Mark Word里预留通用哈希码的存储位。当你第一次调用Integer实例的hashCode()(或者JVM需要用到它,比如放入HashMap时),计算后的哈希值(对Integer来说就是它的value)会缓存到这里,后续调用直接读取缓存,不用重复计算。 - 存储锁相关数据:如果对象进入偏向锁状态,这部分会存储持有偏向锁的线程ID和epoch值;如果是轻量级锁状态,则会存储线程栈上的锁记录指针。
- 默认状态:如果对象还没计算过哈希码,也没进入锁状态,这部分在JOL输出里通常会显示为全0。
你可以用JOL的CLI命令验证:运行jol-cli internals java.lang.Integer,然后手动调用实例的hashCode()后再看对象头,中间的4字节(偏移4-7的位置)就会出现对应的哈希值了。
内容的提问来源于stack exchange,提问作者Node.JS
相关产品推荐
相关产品推荐

