您的位置:首页 > 编程语言 > Java开发

Java对象内存布局 - 小分析

2013-09-16 20:30 246 查看
csdn 博文:

参考:
http://www.codeinstructions.com/2008/12/java-objects-memory-structure.html
Java Objects Memory Structure
http://www.importnew.com/1305.html
Java对象内存结构

上面java objects memory structure的译文
http://icyfenix.iteye.com/blog/1145044
内存篇:HotSpot虚拟机对象探秘
http://www.cnblogs.com/Lelpuchcr/archive/2013/06/11/3131862.html
由内存布局引发的思考

规则list

1, 每个对象大小,都是8byte的倍数

2, class attributes are ordered like this: first longs and doubles; then ints and floats; then chars and shorts; then bytes and booleans, and last the references. The attributes are aligned to their own granularity.

3, Fields that belong to different classes of the hierarchy are NEVER mixed up together. Fields of the superclass come first, obeying rule 2, followed by the fields of the subclass.

4, Between the last field of the superclass and the first field of the subclass there must be padding to align to a 4 bytes boundary.

5, When the first field of a subclass is a double or long and the superclass doesn't align to an 8 bytes boundary, JVM will break rule 2 and try to put an int, then shorts, then bytes, and then references at the beginning of the space reserved to the subclass
until it fills the gap.

规则1: 每个对象大小,都是8byte的倍数。

1,对象与对象之间是8byte对齐。

2,对象内各field之间,如果需要padding,按4byte padding,不足4个,会填充到4个

<<<<

1, 由于HotSpot VM的自动内存管理系统要求对象起始地址必须是8字节的整数倍,换句话说就是对象的大小必须是8字节的整数倍。

2, 这个例子很容易验证。

使用附件中的‘Instrumentation_demo’,随便new一个对象,然后看下结果

object header

<<

每个对象都有object header

In the Sun JVM, every object (except arrays) has a 2 words header

The first word contains the object's identity hash code plus some flags like lock state and age

the second word contains a reference to the object's class.

为了支持反射、GC、同步等功能,JVM的实现可能会选择在对象里放置一些VM内部使用的数据,通常放置在对象头(object header)里。这些信息从Java层

不可见,也不会在java.lang.Object的Java层源码里出现。

object header长度

object header 两部分组成

第一部分在64位机器占8个字节,在32位机器上占4个字节

第二部分是一个对象引用。

对象引用在32位机器上占4个字节,在64位机器上有两种情况,开启指针压缩时4个字节;未开启指针压缩是8个字节。

>>

Object没有instance field, 基本类型的包装类也都没有instance field

>>>>

规则2:class attributes are ordered like this: first longs and doubles; then ints and floats; then chars and shorts; then bytes and booleans, and last the references. The attributes are aligned to their own granularity.

<<<<

1, 为了节省内存,所以不按照field定义顺序去布局

2, compactFields

compactFields为true时:

1, 当碰到long/doubles时,会将一些短类型插入long/doubles和header的空隙中。(空隙:64bit 开启压缩指针,header占12个字节,剩下的4个字节就是空隙)

2, 子类之中较窄的变量也可能会插入到父类变量的空隙之中。

这个还没有跑例子,不确定对不对。

指定CompactFields

开启 java -XX:+CompactFields Rule2

关闭 java -XX:-CompactFields Rule2

3, 相同长度的类型按定义顺序。

2, 执行Rule2.java,可以看到每个field的offset。

3, FieldsAllocationStyle

export JAVA_OPTS='-XX:FieldsAllocationStyle=2'

实验了下,这个环境变量加上,好像不会影响field内存布局。

>>>>

对齐,padding

<<<<<<<<<<<

1,对象与对象之间是8byte对齐。

2,对象内各field之间,如果需要padding,按4byte padding,不足4个,会填充到4个

这个跟‘64位,32位’没关系

例:当对象中有两个field,一个byte类型,一个对象引用类型,可以看到byte类型和对象引用类型之间的padding是3byte。64bit jvm和32bit jvm的情况是一样的。

2,padding存在的位置:

1, 基本类型和引用类型之间的padding

2, Between the last field of the superclass and the first field of the subclass there must be padding to align to a 4 bytes boundary.

3,header和第一个field之间。

4, 基本类型之间没有

因为基本类型占用内存就4种,8byte,4byte,2byte,1byte,而且它们都是按8,4,2,1的顺序依次排列,各种基本类型任意数量的组合都不会产生padding

继承边界

继承边界上的alignment是按heapOopSize为单位来算的,64位HotSpot VM开压缩指针的时候heapOopSize是4字节,所以继承边界上就是4字节对齐,跟32位HotSpot VM正好一样。

通过继承关系的两个类,每个类只有一个byte成员,就可以清楚地看到继承边界的padding

>>>>>>>>>>>

附件:http://download.csdn.net/detail/shigang_xing/6277567
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: