通过dump分析Java对象在内存中到底占用多大空间?

一、内存结构分析
1、概念:
Shallow Size:Shallow size就是对象本身占用内存的大小,不包含其引用的对象。
retained size: 自身对象+引用对象的retained大小。
2、jvm内存创建对象组成部分
1)对象头包括两部分:
第一部分markword,用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等
第二部分类型指针,虚拟机通过这个指针来确定这个对象是哪个类的实例
2)实例数据
实例数据部分是对象真正存储的有效信息,也是在程序代码中所定义的各种类型的字段内容。无论是从父类继承下来的,还是在子类中定义的,都需要记录起来。
3)填充数据
最后一块对齐填充空间并不是必然存在的,也没有特别的含义,它仅仅起着占位符的作用。这是由于HotSpot VM的自动内存管理系统要求对象起始地址必须是8字节的整数倍,换句话说,就是对象的大小必须是8字节的整数倍。
3、对象头占用空间
1. 在32位系统下,存放 Class引用 指针的空间大小是4字节,MarkWord是4字节,对象头为8字节。
2. 在64位系统下,存放Class引用指针的空间大小是8字节,MarkWord是8字节,对象头为16字节。
3. 在64位开启指针压缩的情况下 -XX:+UseCompressedOops,存放 Class引用 的空间大小是4字节,MarkWord是8字节,对象头为12字节。
4. 如果对象是数组,需要另外增加4字节 ,用来记录数组长度,也就是一个int类型的对象,占4字节
二、确认机器环境情况:
查看机器位数
java -d64 -version

 

查看是否开启压缩
jinfo -flag UseCompressedOops 462238
目前机器JVM内存情况
 
三、对象占用内存分析及优化实战
1、dump内存文件是使用JProfiler分析
2、内存具体情况分析
1)int[]数组占用内存空间分析:
 对象头12byte+2*4数据+ 4(记录数组长度) = 24byte
 
2)字符串分析:
单纯一个String: 的shallowSize 24byte=  对象头(8+4)byte+4byte(字段属性hash)+8byte(long序列号号) 
单纯一个char[] 内存大小 shallowSize  16 btype =  对象头(8+4)byte+4byte(数组长度)
一个String最小占用内存: 40Byte
一个String占用内存大小Retained = ( shallowSize 24byte) +( char[] 的 shallowSize  16 btype) +一个char 2byte*N个字符 = 40 +2N + ( 40 +2N )/8, 然后 补齐到8的倍数 ( 40 +2N )/8 。其中N是字符个数
如规则adowner = 40+2*10 + ( 40+2*10 )/8 = 64
 
 
3)Long占用内存分析
Long 24  = 12Byte(对象头)+8btype + 4byte(对齐补充) 
 
3、优化点
1)时间字符串优化成 int,占用内存效果:64byte->4byte  降低原来 1/16
2)hashMap的key由 String 优化成Long,内存占用优化效果:72byte->24byte  降低原来 1/3
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值