记一次对java对象在内存中的分析

java 对象 占内存大小 计算方式 及 常用类型的占用

HotSpot的对齐方式为8字节对齐

计算公式:

1 (对象头 + 实例数据 + padding) % 8 = 0 
2   // 0 <= padding < 8 

 

对象头的内存布局


1Byte = 8bit,而cpu一次能处理的数据位数是32位和64位也就是4字节和8字节

对象自身的运行数据 占一次cpu

指向对象实例的指针 占 一次cpu

数组比较特殊,因为要把数据长度存到头部,所以又要占 一次cpu

以上可以看出普通对象的对象头有两部分而数组对象有三部分,可以推算出 :

32 位:引用类型 4字节

  |-- 普通对象:对象头 8字节

  |-- 数组对象:对象头 12字节;增加元素时,增加引用,则+4B,增加基本数据类型,则+基本数据类型的长度

64 位:引用类型 8字节 

  |--普通对象:对象头 16字节

  |--数组对象:对象头 24字节;增加元素时,增加引用,则+8B,增加基本数据类型,则+基本数据类型的长度

 

从JDK 1.6 update14开始,64 bit JVM正式支持了 -XX:+UseCompressedOops 这个可以压缩指针,起到节约内存占用的新参数。

启用CompressOops后,会压缩的对象:

• 每个Class的属性指针(静态成员变量)

• 每个对象的属性指针

• 普通对象数组的每个元素指针

当然,压缩也不是万能的,针对一些特殊类型的指针,JVM是不会优化的。

比如指向PermGen的Class对象指针,本地变量,堆栈元素,入参,返回值,NULL指针不会被压缩。


压缩后

 64位压缩后:引用类型 4字节

   |--普通对象:对象头  12字节

   |--数组对象:对象头  16字节;增加元素时,增加引用,则+4B,增加基本数据类型,则+基本数据类型的长度

----因为 java 的跨平台性,所以基本类型的数据在32位和64位上占内存大小是一样的

 

基本数据类型
数据类型 内存占用
byte 1字节
short 2字节
int 4字节
long 8字节
float 4字节
double 8字节
char 2字节
boolean 1字节

 

 

 

 

 

 

 

 

 

 

 

总结
数据类型 引用类型 对象头
32位 64位 32位 64位
普通对象 4字节 8字节 8字节

16字节

数组对象 4字节 8字节 12字节 24字节

 

 

 

 

 

 

 

 

 

如有理解不当或建议,欢迎指正

posted @ 2017-06-05 10:55  不放糖的咖啡  阅读(246)  评论(0编辑  收藏  举报