news 2026/4/15 6:24:56

美团一面:new Object() 在 JVM 中到底占多大内存?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
美团一面:new Object() 在 JVM 中到底占多大内存?

在美团、阿里等大厂的面试中,“一个 Object 对象占多少内存”是一个极其高频的题目。很多候选人认为这是一个考察“背诵能力”的冷门知识,但实际上,它考察的是你对 JVM 内存模型、对象布局以及 CPU 架构的深度理解。今天,我们就来彻底拆解这个看似简单却暗藏玄机的技术点。

一、 为什么我们要纠结这几个字节?

在日常业务开发中,我们很少关注一个对象具体占用了 16 字节还是 24 字节。但在高并发、高吞吐的场景下(如亿级流量的电商大促、海量数据的实时计算),内存就是金钱,内存就是性能

理解对象的内存布局,是进行JVM 调优排查内存溢出(OOM)以及设计高性能缓存组件的基石。

那么,当我们敲下new Object()这行代码时,JVM 堆内存中究竟发生了什么?

二、 庖丁解牛:Java 对象的内存布局

在 HotSpot 虚拟机中,一个对象在内存中的存储布局可以分为三个部分:

  1. 对象头(Header)
  2. 实例数据(Instance Data)
  3. 对齐填充(Padding)

为了更直观地理解,看下图:

1. 对象头(Header)—— 对象的“身份证”

对象头是对象最核心的部分,它包含两类信息:

  • Mark Word(标记字段)
    • 这是对象最“忙碌”的部分。它存储了对象的运行时数据,如:哈希码(HashCode)GC 分代年龄锁状态标志线程持有的锁偏向线程 ID等。

    • 在 64 位虚拟机中,Mark Word 占用8 字节

  • Klass Pointer(类型指针)
    • 对象指向它的类元数据的指针,JVM 通过这个指针来确定这个对象是哪个类的实例。

    • 它的长度取决于是否开启了指针压缩(CompressedOops)。

2. 实例数据(Instance Data)—— 对象的“血肉”

这是对象真正存储有效信息的地方,即我们在代码中定义的各种字段(int, boolean, reference 等)。

  • 对于new Object()来说,因为Object类没有任何字段,所以这部分大小为0

3. 对齐填充(Padding)—— 强迫症的“占位符”

这是最容易被忽视的一点。HotSpot 虚拟机的自动内存管理系统要求对象起始地址必须是 8 字节的整数倍

  • 换句话说,任何对象的大小都必须是 8 的倍数

  • 如果对象头 + 实例数据不是 8 的倍数,JVM 就会用空白数据填充,直到补齐。

三、 深度计算:new Object() 到底多大?

环境假设:我们目前绝大多数服务器都是64 位 JVM。我们将分两种主要情况讨论。

情况 A:64 位 JVM + 开启指针压缩(默认情况)

从 JDK 1.6 update 14 开始,64 位 JVM 默认开启了指针压缩(-XX:+UseCompressedOops)。

  • Mark Word:8 字节
  • Klass Pointer:被压缩为 4 字节
  • 实例数据:0 字节
  • 当前总和:8 + 4 + 0 = 12 字节

注意:12 不是 8 的倍数!

对齐填充:JVM 必须强行填充4 字节,使其达到 16 字节。

结论:16 字节

情况 B:64 位 JVM + 关闭指针压缩

如果你手动设置了-XX:-UseCompressedOops,或者堆内存超过了 32GB(指针压缩会自动失效)。

  • Mark Word:8 字节
  • Klass Pointer:未压缩,占用 8 字节
  • 实例数据:0 字节
  • 当前总和:8 + 8 + 0 = 16 字节

注意:16 已经是 8 的倍数,不需要填充。

结论:还是 16 字节

情况 C:32 位 JVM(古董级环境)

  • Mark Word:4 字节
  • Klass Pointer:4 字节
  • 总计:8 字节

四、 眼见为实:JOL 工具验证

空口无凭,我们使用 OpenJDK 提供的JOL (Java Object Layout)工具来打印对象的内存布局。

引入依赖:

<dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.16</version></dependency>

测试代码:

import org.openjdk.jol.info.ClassLayout;public class ObjectSizeTest {public static void main(String[] args) {Object obj = new Object();// 打印对象布局System.out.println(ClassLayout.parseInstance(obj).toPrintable());}}

控制台输出(JDK 1.8, 64位, 默认开启指针压缩):

java.lang.Object object internals:OFFSET SIZE TYPE DESCRIPTION VALUE0 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 bytesSpace losses: 0 bytes internal + 4 bytes external = 4 bytes total

五、 避坑指南:常见误区

误区 1:指针压缩能减少所有对象的大小?

真相:不一定。 就像new Object(),开启压缩是 8+4+4(填充)=16字节;关闭压缩是 8+8=16字节。对于空对象,指针压缩并没有节省内存空间,只是把“类型指针”占用的空间换成了“填充”空间。但对于包含多个引用字段的复杂对象,指针压缩效果非常显著。

误区 2:数组对象也只占 16 字节?

真相:错误。 数组对象除了对象头,还多了一个4 字节的空间来存储数组长度new int[0]在开启压缩时占用:8(Mark) + 4(Klass) + 4(Length) = 16 字节(正好不需要填充)。

误区 3:所有 CPU 缓存行都是 64 字节?

虽然常见的 x86 架构 CPU 缓存行(Cache Line)通常是 64 字节,这与对象对齐(8 字节)是两个层面的概念。对象对齐是为了让 CPU 无论是读取 32 位还是 64 位数据,都能一次性高效访问,避免跨缓存行读取。

六、 总结与建议

下次面试官问你:“new Object() 占多少内存?”

你可以自信地回答:

“在主流的 64 位 JVM 中,无论是否开启指针压缩,new Object() 都占用 16 字节

区别在于内部结构:

  • 开启压缩:8 字节 Mark Word + 4 字节 Klass Pointer + 4 字节对齐填充。
  • 关闭压缩:8 字节 Mark Word + 8 字节 Klass Pointer。”

💡架构师建议: 在进行海量对象存储设计(如本地缓存、对象池)时,计算内存容量千万不要只算字段大小,对象头和对齐填充的开销(Overhead)往往比你想象的要大得多

https://mp.weixin.qq.com/s/z8d0h-E2wnYggH2An8QR2w

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/31 4:02:52

利用Miniconda创建独立Python环境运行PyTorch项目

利用 Miniconda 构建隔离环境高效运行 PyTorch 项目 在深度学习项目开发中&#xff0c;一个看似不起眼却频繁引发“血案”的问题浮出水面&#xff1a;明明本地跑得好好的模型&#xff0c;换台机器就报错 ModuleNotFoundError&#xff0c;或是因为 PyTorch 版本不兼容导致训练结…

作者头像 李华
网站建设 2026/4/8 16:53:44

Miniconda-Python3.9镜像显著提升AI开发效率的5大理由

Miniconda-Python3.9 镜像如何重塑现代 AI 开发工作流 在人工智能项目日益复杂、迭代速度不断加快的今天&#xff0c;一个常见的场景是&#xff1a;你终于复现了一篇论文的结果&#xff0c;信心满满地把代码交给同事&#xff0c;结果对方运行时却报错——“torch 版本不兼容”…

作者头像 李华
网站建设 2026/4/14 19:26:50

QianKun 前端微服务技术深度解析

一、沙箱机制1.1 原理全局变量隔离&#xff1a;通过代理&#xff08;Proxy&#xff09;对象来拦截和管理全局变量&#xff08;如 window 对象&#xff09;的读写操作&#xff0c;实现全局变量的隔离当微应用尝试访问或修改全局变量时&#xff0c;沙箱会捕获这些操作并进行处理&…

作者头像 李华
网站建设 2026/4/12 18:13:26

读懂 SAP Shared Memory 与 IMODE:从 ST02 的 Mode List 还原一次用户会话的内存旅程

在做 ABAP 开发或 SAP Basis 性能分析时,很多内存相关的疑问并不是 内存不够 这么简单:同一台应用服务器上,几十上百个 Work Process 并发跑着不同用户的不同事务码,为什么有些对象能被所有进程共享,有些对象却只能在某个进程里活着?又为什么你在一个事务里 跳转、返回、…

作者头像 李华
网站建设 2026/4/11 18:29:45

网络技术人才缺口白皮书:哪些赛道正在高薪抢人?

随着信息技术的飞速发展&#xff0c;计算机网络技术已成为现代社会不可或缺的基础设施&#xff0c;深刻影响着各行各业。作为计算机类专业中的重要一员&#xff0c;计算机网络技术专业的毕业生正迎来前所未有的就业机遇。本文将深入探讨计算机网络技术专业的就业方向及前景&…

作者头像 李华