网站首页 > java教程 正文
题外话
对于我们开发人员来说,我们经常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,有一个ObjectSize.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("张三")));
}
来看看打印的结果即可。
如果感觉文章对你有用,欢迎关注交流~也可收藏起来有需要的时候看看
猜你喜欢
- 2024-09-19 “全栈2019”Java第一百一十二章:什么是闭包?
- 2024-09-19 Java两个Set集合判断是否有交集(java set求并集)
- 2024-09-19 从一道面试题说起:GET 请求能传图片吗?
- 2024-09-19 Java设计模式(二十):职责链模式(java责任链模式的应用场景)
- 2024-09-19 32位和64位的JVM应该用哪个?
- 2024-09-19 Mac下安装 JDK17(mac下安装nvm以及node)
- 2024-09-19 Java Web项目部署(二)——JDK、Tomcat
- 2024-09-19 Java Web项目部署(三)-MySQL8(javaweb连接mysql具体步骤)
- 2024-09-19 腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹?
- 2024-09-19 win7下绿色版mysql-5.7.18winx64如何配置
你 发表评论:
欢迎- 最近发表
-
- class版本不兼容错误原因分析(class更新)
- 甲骨文Oracle公司为Java的最新LTS版本做出改进
- 「版本发布」Minecraft Java开发版 1.19.4-pre1 发布
- java svn版本管理工具(svn软件版本管理)
- 我的世界1.8.10钻石在第几层(我的世界1.7.2钻石在哪层)
- Java开发高手必备:在电脑上轻松切换多个JDK版本
- 2022 年 Java 开发报告:Java 8 八年不到,开发者都在用什么?
- 开发java项目,选择哪个版本的JDK比较合适?
- Java版本选型终极指南:8 vs 17 vs 21特性对决!大龄程序员踩坑总结
- POI Excel导入(poi excel导入附件)
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)