分析java对象内存占用

本文探讨了JVM的分代GC如何处理小对象,以及在处理长期存在的缓存对象时可能出现的内存问题。计算对象内存占用的重要性在于避免OOM。文章详细介绍了对象的内存结构,包括Head、Body和Padding,并通过一个Integer实例解释了如何计算对象内存。最后,提到了从JDK1.5开始的Instrumentation接口,该接口简化了对象内存大小的获取。
摘要由CSDN通过智能技术生成

JVM的分代GC法非常适合处理小而短命的对象,这类对象可以很快的在minor GC后清除;但是日常开发中经常需要缓存一些对象,这些对象在经过几次MinorGC后最终会进入老年代;如果这些对象占用太多的内存则会出现OOM,所以应该限制缓存对象集合的内存占用,这样我们就需要计算出每个对象所占用的内存。

怎样计算一个对象的内存呢? 首先需要明白对象的内存结构。
对象的内存结构分为三大块,Head,Body和Padding。

  • Head:

    • class引用:Object中定义getClass()方法来获取对象的Class对象,大家知道class对象是保存在方法区的,也就是说对象中保存着指向class对象的引用,这个引用就在Head中。

      一个引用在32位系统中占用4byte,在64位系统中占用8byte

    • MarkWord :Head中还存放一些其他信息:是否加锁,GC标志位,MinorGC次数,对象hashcode等,这部分空间通常叫作叫MarkWord(32位系统中占用4byte,在64位系统中占用8byte)。

    • 如果对象是数组,head中还存储这数组的长度(4byte)
  • Body:就是对象非static属性所占的空间 (static属性存放在方法区)
  • Padding:java对象以8字节对齐在内存中,如果对象的占用不是8字节的倍数,则会补齐为8的倍数。-padding就是用来补齐的空间

知道了对象的内存结构,就可以计算出对象的内存占用
以一个64位系统中的Integer为例,
1. 计算Head区,8+8=16 (byte),
2. 计算Body区,查看Integer 的源码发现Integer类中只存在一个非static属性 private final int value; 所以Body占4字节,
3. 加入Padding,这样head+body=16+4=20,计算出的位数并不是8的倍数,所以加入4byte padding凑齐。
这样下来一个Integer占用的内存为Header+Body+Padding=16+4+4=24(byte)

对于Integer这种非常简单的类计算非常简单,如果类中存在继承关系,还需计算父类的属性。

这样计算太麻烦了,还好从JDK1.5以后引入了一个Instrumentation接口,调用

Instrumentation#getObjectSize(Object objectToSize)
<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值