「阿里巴巴」程序员最爱new对象,可是,你真的知道一个对象占用多少内存吗?


「阿里巴巴」程序员最爱new对象,可是,你真的知道一个对象占用多少内存吗?
文章图片
「阿里巴巴」程序员最爱new对象,可是,你真的知道一个对象占用多少内存吗?
文章图片
「阿里巴巴」程序员最爱new对象,可是,你真的知道一个对象占用多少内存吗?
文章图片
「阿里巴巴」程序员最爱new对象,可是,你真的知道一个对象占用多少内存吗?
文章图片
概述公司小姐姐今天突然找我聊天 , 那个激动啊 , 然后她突然问我你有对象吗?我心里一愣 , 难道我的春天来了吗?但是接下来一句话让我心灰意冷 啊 , 你知道Object obj=new Object()占多少字节吗?我男朋友问我 , 我内心真的是一万头***奔腾而过啊 , 处于耿直的程序员 , 我们来看一下对象到底占用多少字节 。
Java 对象头内存模型我们先来看看 , 一个Java 对象的内存模型是怎么样的?由于我们的虚拟机是分为32位和64位 , 那肯定它们的模型也是有区别的 , 下面我列出列32位虚拟机和64位虚拟机下的Java对象头内存模型 。
因为我的本地环境是jdk1.864位虚拟机 , 这里我以64位虚拟机(开启指针压缩)来分析 , 因为默认情况下 , jdk1.8 在64位虚拟机默认开启指针压缩 。
Java 对象头主要包括两部分 , 第一部分就是 Mark Word , 这也是 Java 锁实现原理中重要的一环 , 另外一部分是 Klass Word 。
Klass Word 这里其实是虚拟机设计的一个oop-klass model模型 , 这里的OOP是指Ordinary Object Pointer(普通对象指针) , 看起来像个指针实际上是藏在指针里的对象 。 而 klass 则包含 元数据和方法信息 , 用来描述 Java 类 。 它在64位虚拟机开启压缩指针的环境下占用 32bits 空间 。
【「阿里巴巴」程序员最爱new对象,可是,你真的知道一个对象占用多少内存吗?】Mark Word 是我们分析的重点 , 这里也会设计到锁的相关知识 。 Mark Word 在64位虚拟机环境下占用 64bits 空间 。 整个Mark Word的分配有几种情况:
1. 未锁定(Normal): 哈希码(identity_hashcode)占用31bits , 分代年龄(age)占用4 bits , 偏向模式(biased_lock)占用1 bits , 锁标记(lock)占用2 bits , 剩余26bits 未使用(也就是全为0)
2. 可偏向(Biased): 线程id 占54bits , epoch 占2 bits , 分代年龄(age)占用4 bits , 偏向模式(biased_lock)占用1 bits , 锁标记(lock)占用2 bits , 剩余 1bit 未使用 。
3. 轻量锁定(Lightweight Locked): 锁指针占用62bits , 锁标记(lock)占用2 bits 。
4. 重量级锁定(Heavyweight Locked):锁指针占用62bits , 锁标记(lock)占用2 bits 。
5. GC 标记:标记位占2bits , 其余为空(也就是填充0)
以上就是我们对Java对象头内存模型的解析 , 只要是Java对象 , 那么就肯定会包括对象头 , 也就是说这部分内存占用是避免不了的 。 所以 , 在笔者64位虚拟机 , Jdk1.8(开启了指针压缩)的环境下 , 任何一个对象 , 啥也不做 , 只要声明一个类 , 那么它的内存占用就至少是96bits , 也就是至少12字节 。
验证模型我们来写点代码来验证一下上述的内存模型 , 这里推荐openjdk的jol工具 , 它可以帮助你查看对象内存的占用情况 。
首先添加maven依赖
<dependency>
<groupId>org.openjdk.jol</groupId>