当前位置: 首页 > 后端技术 > Java

【HotSpot】一个java对象占用多少空间

时间:2023-04-02 10:26:17 Java

作者:threedayman来源:恒生LIGHT云社区以下内容基于HotSpot虚拟机进行讲解验证。理论知识对象在堆内存中的存储布局可以分为三个部分:对象头(Header)、实例数据(InstanceData)和对齐填充(Padding)。对象头中有两类信息runtimedata:hashcode、GCgenerationage、lockstatusflag、threadheoldedlock、biasedthreadID、biasedtimestamp等类型指针:对象指向其类型元数据的指针,虚拟机通过这个指针来判断这个对象是哪个类的实例。实例数据对象中存储的有效信息是程序代码中定义的各类字段的内容。对齐填充HotSpot虚拟机的自动内存管理系统要求对象的起始地址必须是8字节的整数倍。如果对象占用的空间不是8字节的整数倍,则需要通过alignmentpadding来完成。对象的大小受JVM参数UseCompressedOops的影响。对于64位操作系统,开启压缩指针时对象头大小为12字节,关闭压缩指针时对象头大小为16字节。练习题使用Instrumentation的getObjectSize方法来测量对象的大小。具体代码如下:util.ArrayDeque;导入java.util.Deque;导入java.util.HashSet;导入java.util.Set;公共类SizeOfObject{staticInstrumentationinst;publicstaticvoidpremain(Stringargs,InstrumentationinstP){inst=instP;}/***直接计算当前对象占用的空间,包括当前类和父类的基本类型实例字段大小,

*引用类型实例字段引用大小,总占用空间实例基本类型数组,实例引用类型数组reference自身占用的空间大小;

*但不包括对象本身继承自超类的大小和当前声明的实例引用字段类,以及实例引用数组引用的对象本身的大小

**@paramobj*@return*/publicstaticlongsizeOf(Objectobj){returninst.getObjectSize(obj);}/***递归计算当前对象占用空间的总大小,包括当前类和超类的实例字段大小和实例字段引用对象大小**@paramobjP*@return*@throwsIllegalAccessException*/publicstaticlongfullSizeOf(ObjectobjP)通过wsIllegalAccessException{Setvisited=newHashSet();双端队列<对象>toBeQueue=newArrayDeque<>();toBeQueue.add(objP);长尺寸=0L;while(toBeQueue.size()>0){对象obj=toBeQueue.poll();//sizeOf已经统计了基本类型和引用的长度,包括arraysize+=skipObject(visited,obj)?0L:大小(对象);类tmpObjClass=obj.getClass();if(tmpObjClass.isArray()){//[I,[F基本类型名称的长度为2if(tmpObjClass.getName().length()>2){for(inti=0,len=Array.getLength(obj);ivisited,Objectobj){if(objinstanceofString&&obj==((String)obj).intern()){返回真;}返回visited.contains(obj);}}测试对象大代码packageorg.example;importstaticorg.example.SizeOfObject.fullSizeOf;importstaticorg.example.SizeOfObject.sizeOf;publicclassSizeOfObjectTest{/***-XX:+UseCompressedOops:Header12Padding4=16*-XX:-UseCompressedOops:Header16=24*/staticclassA1{}/***-XX:+UseCompressedOops:Header12+InstanceData4=16*-XX:-UseCompressedOops:Header16+InstanceData4+填充4=24*/staticclassA{inta;}/***-XX:+UseCompressedOops:Header12+InstanceData4+4+padding4=24*-XX:-UseCompressedOops:Header16+InstanceData4+4=24*/staticclassB{inta;诠释乙;}/***-XX:+UseCompressedOops:Header12+4+4+padding/4=24*-XX:-UseCompressedOops:Header16+8+4+padding/4=32*/staticclassB2{intb2a;整数b2b;}/***不要考虑对象头:*4+4+4*3+3*sizeOf(B)*/staticclassCextendsA{intba;B[]as=newB[3];C(){for(inti=0;i
最新推荐
猜你喜欢