详解Java对象头对集合实例内存占用的空间开销

落强吖_4125

落强吖_4125

2026-04-08

926人浏览

原创

对象头由mark word和class pointer组成,在64位hotspot jvm中默认压缩指针下占12字节(数组为16字节);它是所有集合实例的固定内存开销基础,直接影响整体内存占用估算。

详解java对象头对集合实例内存占用的空间开销

Java对象头本身不直接决定集合实例的内存开销,但它作为每个对象(包括集合类如ArrayList、HashMap等)的固定组成部分,构成了所有集合实例的“基础内存税”。理解对象头的结构和大小,是准确估算集合实际内存占用的起点。

对象头由哪几部分组成?

在HotSpot虚拟机中(主流JDK默认),一个Java对象的内存布局包含三块:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。其中对象头又分为两部分:

  • Mark Word(标记字段):存储哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID等。在64位JVM上,未开启指针压缩时占8字节;开启指针压缩(-XX:+UseCompressedOops,默认开启)且未启用压缩类指针时,仍为8字节(HotSpot对Mark Word不做压缩)。
  • Class Pointer(类型指针):指向该对象所属类的元数据(Klass结构体)。在64位JVM开启指针压缩时占4字节;未开启则占8字节。

因此,普通Java对象的对象头大小通常为:12字节(压缩指针)或16字节(非压缩)。注意:数组对象额外多4字节长度字段(length),所以数组对象头为16字节(压缩)或20字节(非压缩)。

集合实例的内存开销 = 对象头 + 字段 + 底层数组 + 对齐填充

以ArrayList<integer></integer>为例(JDK 17,64位JVM,默认开启压缩指针):

  • 对象头:12字节(Mark Word 8B + Class Pointer 4B)
  • 实例字段:3个int型字段(size、modCount)和1个Object[]引用(elementData)。其中两个int各占4B,引用占4B → 共12字节
  • 底层数组:新创建的空ArrayList默认初始化elementData = EMPTY_ELEMENTDATA(共享静态空数组),不额外分配数组对象;若调用ensureCapacity(10),则新建Object[10]数组 → 数组对象头16B + 10×4B元素 = 56B(需按8字节对齐,刚好无需填充)
  • 对象对齐:整个ArrayList对象自身需8字节对齐。当前头+字段=24B,已对齐,无需填充

所以一个空ArrayList(未扩容)仅占24字节;而一个装了10个Integer的ArrayList,其总内存≈24B(ArrayList对象)+ 56B(Object[10]数组)+ 10×16B(10个Integer对象,每个含12B头+4B value + 对齐)= 240B以上——其中对象头贡献了12B(ArrayList)+ 16B(数组)+ 10×12B(Integer)= 148B,占比超60%。

HashMap的开销更复杂,但对象头仍是“固定成本”

HashMap对象本身有对象头(12B)+ 若干字段(loadFactor、threshold、size、modCount、table引用、keySet等,约24–32B),合计约40B左右。但真正吃内存的是其Node[] table底层数组。即使空Map,JDK 8+ 默认延迟初始化,table = null,此时只占对象头+字段;首次put后才创建Node[16](数组对象16B头 + 16×Node对象)。每个Node是内部类对象:对象头12B + 4个字段(hash、key、value、next)共16B → 每个Node至少28B(需对齐到32B)。16个Node就额外增加512B。对象头在这里虽单个体量小,却是每个Node无法省略的“刚性开销”。

如何降低对象头带来的集合内存压力?

对象头大小由JVM决定,不可编程修改,但可通过设计减少对象数量:

  • 优先使用基本类型集合库(如Trove、Eclipse Collections、FastUtil),它们用原始数组替代Object[],避免包装类对象头开销
  • 对大量短生命周期小集合,考虑对象池复用(如Apache Commons Pool),摊薄对象头分配/回收成本
  • 避免过度细粒度集合嵌套(如List>>),每层都新增对象头
  • 确认是否真的需要引用语义:能用数组或扁平结构就不用嵌套集合

不复杂但容易忽略——对象头是每个Java对象的“身份证”,集合再轻量,也逃不开这12或16字节的入场费。算清这笔账,才能真正掌控内存水位。

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
eclipse教程
eclipse教程

php中文网为大家带来eclipse教程合集,eclipse是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。php中文网还为大家带来eclipse的相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.14

570

5

eclipse怎么设置中文
eclipse怎么设置中文

eclipse设置中文的方法:除了设置界面为中文外,你还可以为Eclipse添加中文插件,以便更好地支持中文编程。例如,你可以安装EBNF插件来支持中文变量名,或安装Chinese Helper来提供中文帮助文档。本专题为大家提供eclipse设置中文相关的各种文章、以及下载和课程。

2023.07.24

4786

6

c语言编程软件有哪些
c语言编程软件有哪些

c语言编程软件有GCC、Clang、Microsoft Visual Studio、Eclipse、NetBeans、Dev-C++、Code::Blocks、KDevelop、Sublime Text和Atom。更多关于c语言编程软件的问题详情请看本专题的文章。php中文网欢迎大家前来学习。

2023.11.02

7279

18

Eclipse版本号有哪些区别
Eclipse版本号有哪些区别

区别:1、Eclipse 3.x系列:Eclipse的早期版本,包括3.0、3.1、3.2等;2、Eclipse 4.x系列:Eclipse的最新版本,包括4.0、4.1、4.2等;3、Eclipse IDE for Java Developers等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

2784

5

eclipse和idea有什么区别
eclipse和idea有什么区别

eclipse和idea的区别:1、平台支持;2、内存占用;3、插件系统;4、智能代码提示;5、界面设计;6、调试功能;7、学习曲线。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

622

5

eclipse设置中文全教程
eclipse设置中文全教程

本专题整合了eclipse设置中文相关教程,阅读专题下面的文章了解更多详细操作。

2025.10.10

3066

11

eclipse字体放大教程
eclipse字体放大教程

本专题整合了eclipse字体放大教程,阅读专题下面的文章了解更多详细内容。

2025.10.10

3085

12

eclipse左边栏不见了解决方法
eclipse左边栏不见了解决方法

本专题整合了eclipse左边栏相关教程,阅读专题下面的文章了解更多详细内容。

2025.10.15

408

3

eclipse字体相关教程
eclipse字体相关教程

本专题整合了eclipse字体设置相关教程,阅读专题下面的文章了解更多详细内容。

2025.11.26

834

12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.6万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.4万人学习