[转]Java对象内存占用分析
转载:https://segmentfault.com/a/1190000006933272
http://www.cnblogs.com/zhanjindong/p/3757767.html
java对象内存布局 对象头+实例数据+补充填充
对象头
开启指针压缩(-XX:-UseCompressedOops)的情况下(默认),对象头占用12bytes
不开启指针压缩(-XX:+UseCompressedOops)则占用16bytes。
填充对象
Java对象占用空间是8字节对齐的,即所有Java对象占用bytes数必须是8的倍数。例如,一个包含两个属性的对象:int和byte,并不是占用17bytes(12+4+1),而是占用24bytes(对17bytes进行8字节对齐)
实例数据
原生数据
Type | Range | Default | Size | Example |
---|---|---|---|---|
boolean | true or false | false | 1 bit | true, false |
byte | -128 .. 127 | 0 | 8 bits | 1, -90, 128 |
char | Unicode character or 0 to 65,536 | \u0000 | 16 bits | 'a', '\u0031', '\201', '\n', 4 |
short | -32,768 .. 32,767 | 0 | 16 bits | 1, 3, 720, 22,000 |
int | -2,147,483,648 .. 2,147,483,647 | 0 | 32 bits | -2, -1, 0, 1, 9 |
long | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 | 0 | 64 bits | -4000L, -900L, 10L, 700L |
float | 3.40282347 x 1038, 1.40239846 x 10-45 | 0.0 | 32 bits | 1.67e200f, -1.57e-207f, .9f, 10.4F |
double | 1.7976931348623157 x 10308, 4.9406564584124654 x 10-324 | 0.0 | 64 bits | 1.e700d, -123457e, 37e1d |
对象引用(reference)类型在64位机器上,关闭指针压缩时占用8bytes, 开启时占用4bytes。
对象内存占用
TestObject对象有四个属性,分别为int, double, Byte, char[]类型。在打开指针压缩(-XX:+UseCompressedOops)的情况下,在64位机器上,TestObject占用的内存大小应为:
12(Header) + 4(int) + 8(double) + 4(reference) = 28 (bytes),加上8字节对齐,最终的大小应为32 bytes。
当指针压缩关闭时(-XX:-UseCompressedOops) 如果打开,在64位机器上,TestObject占用的内存大小应为:
16(Header) + 4(int) + 8(double) + 8(reference) = 36 (bytes), 8字节对齐后为 40 bytes。
包装类型
Numberic Wrappers +useCompressedOops -useCompressedOops
Byte, Boolean 16 bytes 24 bytes
Short, Character 16 bytes 24 bytes
Integer, Float 16 bytes 24 bytes
Long, Double 24 bytes 24 bytes
数组
在64位机器,数组对象的对象头占24bytes 启动压缩了占用16字节,比普通对象占用内存多是因为需要额外的空间存储数组的长度。基础数据类型数组占用的空间包括数组对象头以及基础数据类型数据占用的内存空间
由于对象数组中存放的是对象的引用,所以对象数组本身的大小=数组对象头+length * 引用指针大小,总大小为对象数组本身大小+存放的数据的大小之和。
new Integer[3]:
关闭压缩:
Integer数组本身:24(header) + 3 * 8(Integer reference) = 48 bytes;
总共:48 + 3 * 24(Integer) = 120 bytes。
关闭压缩:
Integer数组本身:24(header) + 3 * 8(Integer reference) = 48 bytes;
总共:48 + 3 * 24(Integer) = 120 bytes。
String
在JDK1.7及以上版本中,String包含2个属性,一个用于存放字符串数据的char[], 一个int类型的hashcode,
因此,在关闭指针压缩时,一个String本身需要 16(Header) + 8(char[] reference) + 4(int) = 32 bytes。
除此之外,一个char[]占用24 + length * 2 bytes(8字节对齐), 即一个String占用的内存空间大小为:
网友评论