『』你写的Java对象究竟占多少内存?( 二 )
上面这行代码会解析你新建一个NullObject对象 , 占用了多少内存 。我们执行看看结果如何:
文章图片
文章图片
这里我们发现结果显示:Instance size:16 bytes,结果就是16字节 , 我们之前预测的12字节不一样 , 为什么会这样呢?我们看到上图中有3行 object header , 每个占用4字节 , 所以头部就是12字节 , 这里和我们的计算是一致的 , 最后一行是虚拟机填充的4字节 , 那为什么虚拟机要填充4个字节呢?内存对齐
想要知道为什么虚拟机要填充4个字节 , 我们需要了解什么是内存对齐?
我们程序员看内存是这样的:
文章图片
文章图片
上图表示一个坑一个萝卜的内存读取方式 。但实际上 CPU 并不会以一个一个字节去读取和写入内存 。相反 CPU 读取内存是一块一块读取的 , 块的大小可以为 2、4、6、8、16 字节等大小 。块大小我们称其为内存访问粒度 。如下图:
文章图片
文章图片
假设一个32位平台的 CPU , 那它就会以4字节为粒度去读取内存块 。那为什么需要内存对齐呢?主要有两个原因:
平台(移植性)原因:不是所有的硬件平台都能够访问任意地址上的任意数据 。例如:特定的硬件平台只允许在特定地址获取特定类型的数据 , 否则会导致异常情况 。
性能原因:若访问未对齐的内存 , 将会导致 CPU 进行两次内存访问 , 并且要花费额外的时钟周期来处理对齐及运算 。而本身就对齐的内存仅需要一次访问就可以完成读取动作 。
我用图例来说明 CPU 访问非内存对齐的过程:
文章图片
文章图片
在上图中 , 假设CPU 是一次读取4字节 , 在这个连续的8字节的内存空间中 , 如果我的数据没有对齐 , 存储的内存块在地址1 , 2 , 3 , 4中 , 那CPU的读取就会需要进行两次读取 , 另外还有额外的计算操作:
CPU 首次读取未对齐地址的第一个内存块 , 读取 0-3 字节 。并移除不需要的字节 0 。
CPU 再次读取未对齐地址的第二个内存块 , 读取 4-7 字节 。并移除不需要的字节 5、6、7 字节 。
合并 1-4 字节的数据 。
合并后放入寄存器 。
所以 , 没有进行内存对齐就会导致CPU进行额外的读取操作 , 并且需要额外的计算 。如果做了内存对齐 , CPU可以直接从地址0开始读取 , 一次就读取到想要的数据 , 不需要进行额外读取操作和运算操作 , 节省了运行时间 。我们用了空间换时间 , 这就是为什么我们需要内存对齐 。
回到Java空对象填充了4个字节的问题 , 因为原字节头是12字节 , 64位机器下 , 内存对齐的话就是128位 , 也就是16字节 , 所以我们还需要填充4个字节 。非空对象占用内存计算
我们知道了一个空对象是占用16字节 , 那么一个非空对象究竟占用多少字节呢?我们还是写一个普通类来验证下:public class TestNotNull {private NullObject nullObject=new NullObject();private int a; }
这个演示类中引入了别的对象 , 我们知道int类型是占用4个字节,NullObject对象占用16字节 , 对象头占12字节 , 还有一个很重要的情况 NullObject在当前这个类中是一个引用 , 所以不会存真正的对象 , 而只存引用地址 , 引用地址占4字节 , 所以总共就是12+4+4=20字节 , 内存对齐后就是24字节 。我们来验证下是不是这个结果:public static void main(String[] args) {//打印实例的内存布局System.out.println(ClassLayout.parseInstance(new TestNotNull()).toPrintable());//打印对象的所有相关内存占用System.out.println(GraphLayout.parseInstance(new TestNotNull()).toPrintable());//打印对象的所有内存结果并统计System.out.println(GraphLayout.parseInstance(new TestNotNull()).toFootprint());}
推荐阅读
- 软件:看看我写的啥破程序!就值3000?
- 『JavaScript』种草 ES2020 八大新功能
- Java虚拟机:SpringCloud的限流、降级和熔断——Hystrix
- 国产机:iPhone12刘海消失,可能又是国产机模仿的对象!但发布会很晚?
- [函数式]JavaScript面试问题:函数式编程
- @参加Java培训班能达到什么水平以及当前应该注重哪个技术的学习
- ##B站上被下载达5166万次的Python+Java编程视频教程,全套免费领取
- [映维网]苹果最新AR专利可用多设备辅助实现更稳定虚拟对象定位
- 数据挖掘@AI研习丨优秀博士学位论文:面向互联网金融微观对象的数据挖掘
- 『什么值得买』一套适合小白抄写的装机作业