Redian新闻
>
支付宝一面:一个 Java 对象到底有多大?被问傻眼了!!

支付宝一面:一个 Java 对象到底有多大?被问傻眼了!!

公众号新闻
作者:李小武
来源:http://blog.lichengwu.cn/

编写Java代码的时候,大多数情况下,我们很少关注一个Java对象究竟有多大(占据多少内存),更多的是关注业务与逻辑。但是殊不知,在我们不经意间,大量的内存被无形地浪费了。

一个Java对象到底有多大?


想要精确计算一个Java对象占用的内存,首先要了解Java对象的结构表示。

Java对象结构


一个Java对象在Heap的表示,可以分为三部分:

  • Object Header
  • Class Pointer
  • Fields

每个普通Java对象在堆(heap)中都有一个头信息(object header),头信息是必不可少的,记录着对象的状态。
32位与64位占用空间不同,在32位中:
hash(25)+age(4)+lock(3)=32bit

64位中:
unused(25+1)+hash(31)+age(4)+lock(3)=64bit


我们知道,在Java中,一切皆对象;每个类都有一个父类,Class Pointer就是当前对象父类的一个指针,在32位系统中,这个指针为4byte;在64位系统中,如果开启指针压缩(-XX:+UseCompressedOops)或者JVM堆的最大值小于32G,这个指针也是4byte,否则是8byte。

2024最新架构课程,对标培训机构

👉点击查看:Java成神之路-进阶架构视频!


关于字段(Fields),这里指的是类的实例字段;也就是说不包括静态字段,因为这个字段是共享内存的,只会存在一份。

下面以32位系统为例子,计算一下java.lang.Integer到底占用多大内存:
Object Header 和 Pointer 都是固定的,4+4=8byte;再看看字段,只有这一个,表示数值:
/** * The value of the <code>Integer</code>. * * @serial */private final int value;

一个int在java中占据4byte,所以Integer的大小为4+4+4=12byte。

这个结果对吗?不对!还有一点没有说:在java,对象占用的heap大小是8位对齐的,上面的12byte没有对齐,所以需要补位4byte。结果是16byte!

另外,在Java中还有一种特殊的对象,数组!没错,这个对象有点特殊,它比其他对象多了一个属性:长度(length)。所以我们计算数组长度的时候,需要额外加上一个长度的字段,即一个int的大小。

例如:int[] arr = new int[10];

arr的占用heap大小为:
4(object header)+4(pointer)+4(length)+4*10(10int大小)=52byte 由于需要8位对齐,所以最终大小为`56byte`。


节约内存原则


在了解了对象的内存使用情况后,我们可以简单算一笔帐。一个java.lang.Integer占用16byte,而一个int占用4byte,4:1的比例!也就是说整数的类类型是基本类型内存的4倍!

由此我们得出第一个节约内存的原则:

1)尽量使用基本类型,而不是包装类型。


数据库建表的时候字段类型需要仔细推敲,同样JavaBean中的属性字段类型也需要仔细斟酌。不要吝啬使用short,byte,boolean,如果短类型能放下数据,尽量不要使用更长的类型。

一个long比一个int才多4byte,但是你要想,如果内存中有100W个long,那就白白浪费了约4MB空间,不要小看这一点点的空间浪费,因为随便一个跑着在线应用的JVM中,对象都能达到上千万!内存是节省出来的。

所以:


2)斟酌字段类型,在满足容量前提下,尽量用小字段。


你知道一个ArrayList集合,如果里面放了10个数字,占用多少内存吗?让我们算算:

ArrayList中有两个字段:
/** * The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffer. */private transient Object[] elementData;
/** * The size of the ArrayList (the number of elements it contains). * * @serial */private int size;

Object Header占4byte,Pointer占4byte,一个int字段(size)占4byte,elementData数组本身占12(4+4+4),数组中10个Integer对象占10×16。所以整个集合空间大小为4+4+4+12+160=184byte。

如果我们用int[]代替集合呢,12+4×10=52byte,对其后56byte。

集合跟数组的比例是184:56,超过3:1了!

所以我们的第三个建议是:


3)如果可能,尽量用数组,少用集合。


数组中是可以使用基本类型的,但是集合中只能放包装类型!

如果实在需要使用集合,推荐一个比较节约内存的集合工具,fastutil。这里面包含了JKD集合中绝大部分的实现,而且比较省内存。


4)小技巧


在上面的三个原则基础上,提供两个小技巧。
  • 时间用long/int表示,不用Date或者String。
  • 短字符串如果能穷举或者转换成ascii表示,可以用long或者int表示。

小技巧跟具体的场景是数据有关系,可以根据实际情况进行激进优化节省内存。

总结


性能和可读性向来就有些矛盾,在这里也是,为了节约内存,不得不进行取舍,代码丑陋了一些,可读性差了一些,还好能省下一些内存。

上面的原则在确实需要节约内存的时候,不妨可以试试!

PS:如果觉得我的分享不错,欢迎大家随手点赞、在看。

(完)




加我"微信获取一份 最新Java面试题资料

请备注:666不然不通过~


最近好文


1、不好意思,Mybatis Plus 该换了!

2、MySQL中update“经典”的坑,这样写语句,直接劝退!

3、SpringBoot:一个注解就能帮你下载任意对象

4、Controller 层代码就该这么写,简洁又优雅!

5、一台服务器最大能支持多少条 TCP 连接



最近面试BAT,整理一份面试资料Java面试BAT通关手册,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:关注公众号并回复 java 领取,更多内容陆续奉上。
明天见(。・ω・。)



微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
中国汽车市场的规模,到底有多大?| 罗辑思维捐赠13亿,雷军的商业版图到底有多大?马斯克个人传记来了:一面富翁一面恶魔?小行星袭击地球,威胁究竟有多大?地球爆炸,明天放假!!厄尔尼诺现象到来,悉尼海滩最长宽涨了59米,多个热门海滩更大了直球式恋爱到底有多爽!!!Scuba Oversized Java: 全拉链带帽 vs 半拉链立领厄尔尼诺现象到来,悉尼海滩最多宽了59米,多个热门海滩更大了明晚那啥!!!!!!双11平台战报增长另一面:有商家吐槽氛围感弱销售远不及以往杭州亚运会支持支付宝和10个境外钱包移动支付;拉勾招聘联合知乎启动“2024秋招通关指南”;​第四范式宣布港交所上市计划……福建夫妻收养了一个女弃婴,长大后带回家个男朋友,养女父母一看却傻眼了华为“花瓣支付”来了,不直接对标微信、支付宝……中国向美释善意,准万事达发卡,绑定支付宝就能扫码支付傻眼了!外国游客怒曝遭中餐馆“宰客”:一只螃蟹$924!视频号和抖音的差距,到底有多大?视频号和抖音的差距到底有多大?zt寿命也是时势之一 Kung Fu亚运有多火?支付宝亚运小程序互动量近60亿,场馆周边消费大涨3倍一个县委书记的权力到底有多大?小米澎湃 OS 官宣,告别 MIUI / 苹果发布两款新品 / 华为称花瓣支付不与支付宝微信竞争世界折叠的另一面:弥合裂缝的新中国样本徘徊在加拿大落基山脉(二)Poem by yy56同一件衣服,会穿搭和不会穿搭的妈妈,差距到底有能多大?华人注意!再不买就别买了!利率逼近8%!!!!!!!!几百元和上万元的冲锋衣,到底差距有多大?李强私下见拜登,转达习近平歉意联邦催办令到底有多快?“一剂猛药”4天搞定!!!lulu折扣区更新了,大量scuba(绿金、Java)define打折,Blissfeel 运动鞋黑色才79捐赠 13 亿,雷军的商业版图到底有多大?提问 | 毕业留港还是回内地,两边职场差异到底有多大?中国人的三鲜宇宙,到底有多大?痛”字的草书书法华人傻眼了!600万的房子,1个月被窃6次,损失近百万!9点1氪:微信支付与三大运营商条码支付互联互通;小杨哥称11月12日搬入1亿元新大楼;腾讯支付宝美团等将以原生方式适配鸿蒙生态字节一面:post为什么会发送两次请求?
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。