码迷,mamicode.com
首页 > 编程语言 > 详细

Java对象的内存布局

时间:2015-08-14 13:51:08      阅读:117      评论:0      收藏:0      [点我收藏+]

标签:java   对象   内存   布局   

最近在写一个C++ 和java的socket通信程序,需要把收到的字节流转存到一个对象,引申出了这个问题,查找了一些网上的资料,总结如下

本文只包含简单java对象的内存布局,不考虑继承的情况


 Java类的一个实例在内存中包含 对象头,非静态数据成员和对齐数据


静态数据成员,方法成员为类的所有实例共享,不保存在某个对象实例里


对象头的大小取决于于JVM的实现,同一个JVM,普通对象,数组对象,内部对象的对象头大小又有区别。


基本数据类型的大小JVM规范有明确定义,但引用类型在32bit JVM下是4字节,64bit JVM下是8字节(不启用指针压缩参数UseCompressedOops)。


32bit JVM 和 64bit JVM一般都是8字节(64 bit)对齐。

 

一个64bit JVM里面一个基本对象内存布局可能如下所示

 技术分享

数组对象的对象头是24字节,除去16字节基本信息,再加4字节长度数据,4字节对齐数据。另外,对象数组的每一个元素保存的是对象的引用。

非静态的内部对象的对象头也是24字节,16字节的基本信息,加上一个外部类的引用8字节,64bit JVM是8字节,32bit JVM 是4字节加上对齐数据4字节。

如果对象的成员中,含有其他对象比如数组,字符串,这个对象只保存这些成员对象的引用,这些成员对象的内存并不直接包含在这个对象的内存中,在它之外。 


非静态成员在对象内存中的位置和声明顺序是一致的吗?未必


我查找到了一篇相关博客,写于2008年http://www.importnew.com/1305.html

里面提到 Sun VM(现在已经是Oracle VM了,,,)并没有按照属性声明时的顺序进行内存布局,为了节省内存采用了以下顺序

1. 双精度型(doubles)和长整型(longs)

2. 整型(ints)和浮点型(floats)

3. 短整型(shorts)和字符型(chars)

4. 布尔型(booleans)和字节型(bytes)

5. 引用类型(references)

 

这篇博客提到了5个规则

规则1:任何对象都是8个字节为粒度进行对齐的。

规则2:类属性按照如下优先级进行排列:长整型和双精度类型;整型和浮点型;字符和短整型;字节类型和布尔类型,最后是引用类型。这些属性都按照各自的单位对齐。

规则3:不同类继承关系中的成员不能混合排列。首先按照规则2处理父类中的成员,接着才是子类的成员。

规则4:当父类中最后一个成员和子类第一个成员的间隔如果不够4个字节的话,就必须扩展到4个字节的基本单位

规则5:如果子类第一个成员是一个双精度或者长整型,并且父类并没有用完8个字节,JVM会破坏规则2,按照整形(int),短整型(short),字节型(byte),引用类型(reference)的顺序,向未填满的空间填充。

 

所以这个规则还是比较复杂的

这篇博客写于2008年,JVM的实现很可能已经变化,而且JVM版本众多,了解这么多各自的规范是一件比较麻烦的事,从实用的角度来说,可以只了解某个对象的布局

openJDK提供了一个工具,可以查看对象的内存布局,这篇博客里面介绍了这个工具http://blog.csdn.net/aitangyong/article/details/46416667,可以使用这个工具进行分析。


说明:

本文由giantpoplar发表于CSDN

文章地址 http://blog.csdn.net/giantpoplar/article/details/47657377

转载请保留本说明


版权声明:本文为博主原创文章,未经博主允许不得转载。

Java对象的内存布局

标签:java   对象   内存   布局   

原文地址:http://blog.csdn.net/giantpoplar/article/details/47657377

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!