题外话
对于我们开发人员来说,我们经常new一个对象就拿来使用。
但是在底层具体这个对象在内存中是怎么存放的呢?
可能有的人会说知道这些又有啥用呢,天天crud拧螺丝。
嗯,我也无法反驳~我的想法是知道总比不知道好,现在内卷挺严重的,比别人多知道点总归没坏处。其实这部分东西在面试中或多或少会遇到,尤其是大厂。
好了,言归正传,本次讲的是对于64位机器来说的。
首先对象分三类来说
对于普通对象来说第一个部分:对象头中8个字节的markword
第二部分:4字节的ClassPointer(默认开启压缩
-XX:+
UseCompressedClassPointers ,不开启就是8字节)第三部分:实例数据实际占用的字节我爱线报网每日持续更新海量各大内部创业教程数
第四部分:Padding对齐,8的倍数
举个栗子,这是一道面试题:问Object占用多少个字节: Object object=new Object; 1、8个字节markword 2、默认开启指针压缩,4个字节(指向Object.class的指针) 3、没有实例数据,0个字节 4、Padding对齐意思就是前面几个部分加起来是不是8的倍数, 前面一共12个字节,我们想让他对齐,所以再补4个字节就ok了 所以一共是8+4+4=16个字节对于数组对象来说和普通对象的区别在于第三部分多了一个数组长度。
举个栗子:int[] array=new int[]; 1、8个字节markword 2、默认开启指针压缩我爱线报网每日持续更新海量各大内部创业教程,4个字节 3、数组的长度4字节 4、数组的数据,0个字节 因为8+4+4=16正好满足8的倍数,不需要对齐,所以它也占16个字节。对于含有引用类型成员变量的对象来说什么意思呢,还是得举个栗子说明
比如我们定义一个类叫Person,它只有一个String类型的属性name。 class Person{ private String name; //省略 无参构造 和有参构造 } 1、8个字节markword 2、默认开启指针压缩,4个字节 3、此处有个成员变量name,它是引用类型String。 name在开启压缩-XX:+UseCompressedOops的话是4个字节,不开启就是8个字节 4我爱线报网每日持续更新海量各大内部创业教程、因为8+4+4=16正好满足8的倍数,不需要对齐,所以它也占16个字节。此处需要注意的是第三部分,这里有个压缩叫UseCompressedOops,它和UseCompressedClassPointers不一样。oops意思就是ordinary object pointers。
最后我们怎么看到到底开启没开启压缩呢,可以通过下面的命令观察虚拟机的配置:
java -XX:+PrintCommandLineFlags -version这是我本地的配置
需要说明的是-XX:+PrintCommandLineFlags中的+代表开启,-就代表不开启
验证
如果想自己验证一下可以通过java agent,有一个O我爱线报网每日持续更新海量各大内部创业教程bjectSize.jar引入到自己项目中,然后运行时加入参数:
-javaagent:xxx\ObjectSize.jar public static void main(String[] args) { System.out.println(ObjectSizeAgent.sizeOf(new Object())); System.out.println(ObjectSizeAgent.sizeOf(new int[] {})); System.out.println(ObjectSizeAgent.sizeOf(new Person(“张三”))); }来看看打印的结果即可我爱线报网每日持续更新海量各大内部创业教程。
如果感觉文章对你有用,欢迎关注交流~也可收藏起来有需要的时候看看
给力项目:线报网会员可免费下载 加入会员友情提醒: 请尽量登录购买,防止付款了不发货!
QQ交流群:226333560 站长微信:qgzmt2