java 中new一个java new对象内存溢出占多少内存

[Java拾遗]Java对象大小探究 - 每天一小步 - ITeye技术网站
博客分类:
&&& 平时我们不会关心生成的对象到底在JVM中占据多少内存,当发生像OutOfMemory或JVM内存异常增加或减少时才会花精力研究到底发生了什么事情。如果当我们发现有些对象确实很大,但超过我们预期时,我们就该关心下我们所期望创建的每个对象大致会在JVM中占用多少内存呢。这节我会试着以一个更循序诱导的方法来描述,希望可以说的更明白,下面开始:
当遇到OutOfMemory时我们该怎么办?
&&& 一般这个时候,作为我们程序员,心都会焦了,急于想知道到底是哪些对象引起内存不足。我们要做的就是dump heap,然后抓出来分析。这里有一张前些时间我也遇到的OOM问题截图:
&&& 从图上可以抓到“凶手”,剩下的事情就简单多了。
&&& 有个问题:如果现在没有遇到OOM,那我们怎样对某个对象大小有个理性评估呢?
使用Java Instrumentaion来评估每个对象的大小
&&& Java Instrumentation机制为程序运行提供agent,它的附带功能就是获得已经初始化并准备运行的那个对象大小。这里我采用了提供的一个包装util类,方便我们查看对象大小。Jar文件在附件中
&&& 我们的目标类像这样:
public class BytesDemo {
public static void main(String[] args) {
BytesDemo demo = new BytesDemo();
System.out.println("Object size : " + MemoryUtil.memoryUsageOf(demo));
&&& 这个程序在运行时,它会显示多少呢?
&&& (这里可以看到,我的运行是使用了classmexer.jar,并且运行在class文件所在的编译目录,如果你不能获得这样的输出结果,那么请检查classmexer.jar是否放对位置和是否在class文件所在目录上执行java)
&&& 如果我们的目标类变成这样
public class BytesDemo {
private List&String&
public static void main(String[] args) {
BytesDemo demo = new BytesDemo();
demo.cache = new ArrayList&String&();
demo.cache.add("firstKey");
System.out.println("Object size : " + MemoryUtil.deepMemoryUsageOf(demo));
&&& 请注意,这里新增加了了一个属性,而且对MemoryUtil调用的方法也不一样,它的结果是:
对象与对象之间的关系
&&& 对象都存储于JVM堆中,对象与对象之间通过引用链接-直接指向目标对象的物理位置。这里有一张图,是我自己对堆内对象存储情况的理解,事实可能有些不一致,仅仅是让我们有直观印象
&&& 每个对象的物理存储可以分为两部分:Header及该对象的所有对象属性值(不包括static属性)。Hotspot VM限定每个对象header是2个word,word是JVM内部的存储最小单位,当前Hotspot定义的word大小是4字节,所以header共是8个字节。Header中应当包含着本对象的hashCode,对象锁及与GC相关的生存周期信息等。对象属性分为两部分:基本类型属性与对象引用。Java事先定义了所有基本类型的占用位数,如下表:
&&& 基本类型对象属性依上表占用着堆内存,而每个对其它对象的引用是规定占用一个word,也就是4个字节。像上面第二个目标类中新增加一个对象引用cache,那么这个引用属性就只占用4个字节。
&&& 正常的对象引用也有两种:普通对象与数组。数组也是正常对象,只不过,它除了header外还有4个字节表示当前数组的长度是多少,那么我们也可以认为数组对象的header长度就是12个字节了。
&&& 在这里要特别强调的是如果某个普通对象就包含一个byte属性,那么它的对象大小应该是9个字节。而JVM为了malloc与gc方便,指定分配的每个对象都需要是8字节的整数倍,那么对象大小就不再是9个字节,而应该是16个字节。
&&& 在了解上面的这些对象计算规则后,也请大家计算上面两个目标类的对象大小是否符合预期。
&&& 从最上面的一张图上看到了两个名词: shallow size 和 retained size。Shallow表示本对象自身的大小是多少。本对象可能会直接或间接引用其它很多对象,如果被引用的对象仅仅被本对象所引用,那么当本对象无用被GC时,那么本对象所引用的对象也会被GC。Retained就表示如果当本对象被GC时能相关地减少的内存量。这里有个说的十分详细。
类的继承关系对对象大小的影响
&&& 类如果有继承关系,那么按Java的定义,如果某个子类想要被初始化,就得先初始化自己的父类,这样子类对象其实也包含着所有其父类的非static属性。这种关系同样作用于像内部类这种结构里。
参考资料:
1.
下载次数: 263
浏览: 575905 次
来自: 杭州
分析很好!
Normal case : nodes count : 50A ...
tdttyl.cwm 写道runjia1987 写道我想知道, ...
那个index哪里你写的按位异或操作吧!不是按位与操作吧
runjia1987 写道我想知道,如果key的哈希冲突了,乍 ...}

我要回帖

更多关于 java new 泛型对象 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信