javaObject类占用内存大小计算

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

javaObject类占用内存大小计算
在Java中,一个空Object对象的大小是8byte,这个大小只是保存堆中一个没有任何属性的对象的大小。

看下面语句:
1.Object ob = new Object();
这样在程序中完成了一个Java对象的生命,但是它所占的空间为:4byte+8byte。

4byte是上面部分所说的Java栈中保存引用的所需要的空间。

而那8byte则是Java堆中对象的信息。

因为所有的Java非基本类型的对象都需要默认继承Object对象,因此不论什么样的Java 对象,其大小都必须是大于8byte。

有了Object对象的大小,我们就可以计算其他对象的大小了。

1.Class NewObject {
2.int count;
3.boolean flag;
4.Object ob;
5.}
其大小为:空对象大小(8byte)+int大小(4byte)+Boolean大小(1byte)+空Object引用的大小(4byte)=17byte。

但是因为Java在对对象内存分配时都是以8的整数倍来分,因此大于17byte的最接近8的整数倍的是24,因此此对象的大小为24byte。

本文中,我们讨论一个问题:如何计算(或者说,估算)一个Java 对象占用的内存数量?
通常,我们谈论的堆内存使用的前提是以“一般情况”为背景的。

不包括下面两种情形:
1.某些情况下,JVM根本就没有把Object放入堆中。

例如:原则上讲,一个小的thread-local对象存在于栈中,而不是在堆中。

2.被Object占用内存的大小依赖于Object的当前状态。

例如:Object的同步锁是否生效,或者,Object是否正在被回收。

我们先来看看在堆中单个的Object长什么样子
在堆中,每个对象由四个域构成(A、B、C 和D),下面我们逐个解释一下:
1.A:对象头,占用很少的字节,表述Object当前状态的信息
2.B:基本类型域占用的空间(原生域指 int、boolean、short等)
3.C:引用类型域占用的空间(引用类型域指其他对象的引用,每个引用占用4个字节)
4.D:填充物占用的空间(后面说明什么是填充物)
下面我们对A、B、C 和 D 逐一解释
A:对象头
内存中,每个对象占用的总空间不仅包含对象内声明的变量所需要的空间,还包括一些额外信息,比如:对象头和填充物。

“对象头”的作用是用来记录一个对象的实例名字、ID 和实例状态(例如,当前实例是否“可到达”,或者当前锁的状态等等)。

在当前的JVM版本中(Hotspot),“对象头”占用的字节数如下:
1.一个普通对象,占用8 bytes
2.数组,占用 12 bytes,包含普通对象的 8 bytes + 4 bytes(数组长度)
B:基本类型
boolean、byte 占用 1 byte,char、short 占用 2 bytes,int、float 占用 4 bytes,long、double 占用 8 bytes
C:引用类型
每个引用类型占用 4 bytes
D:填充物
在Hotspot中,每个对象占用的总空间是以8的倍数计算的,对象占用总空间(对象头+声明变量)不足8的倍数时候,自动补齐。

而,这些被填充的空间,我们可以称它为“填充物”。

我们看下具体实例:
1.一个空对象(没有声明任何变量)占用 8 bytes -- > 对象头占用 8 bytes
2.只声明了一个boolean类型变量的类,占用 16 bytes --> 对象头(8 bytes) + boolean (1 bytes) + 填充物(7 bytes)
3.声明了8个boolean类型变量的类,占用16 bytes --> 对象头(8 bytes) + boolean (1 bytes) * 8
通过上面的实例,更有助于我们理解。

相关文档
最新文档