JVM优化机制好诡异
long i[] = new long[1000000];for(int j = 0; j < 1000000; j++) {i[j]= 0l;}
预算一个long占8个byte
* 8000000/(1024*1024) = 7.62939453125MB
完全正确。
Long i[] = new Long[1000000];for(int j = 0; j < 1000000; j++) {i[j]= 0l;}
如果把Long按对象计算的话,引用占4byte,空对象占8byte,至少12byte吧。其实我理解错了。
Jvm对这种包装类型的自动拆箱和装箱机制在存储上进行了优化。
结果你会发现Long只占了4字节,这是为什么,好像Long自动优化成了int。看来我理解错了,jdk1.6会对包装类型进行优化,所以Java对象中应该定义对象的属性为包装类型或者基本类型都是浮云,有的时候包装类型反而占的存储更少
100W
基本类型
数据类型预计占存实际占存结果
int3.8146972656253.81471252441406225OK
short1.90734863281251.90736389160156245OK
long7.629394531257.62940979003906225OK
float4.2148208618164063.81471252441406225OK
double7.629394531257.62940979003906225OK
char1.90734863281251.90736389160156245OK
包装类型
数据类型预计占存实际占存结果
Integer[存储优化]3.8146972656253.81471252441406225OK
Short[存储优化]3.8146972656253.81471252441406225OK
Long[存储优化]3.8146972656253.81471252441406225OK
Float19.07348632812518.99338531494140625不理想
Double19.07348632812518.99338531494140625不理想
Object11.44409179687511.27165222167968725不理想
String3.8146972656253.81471252441406225OK
Char[存储优化]3.8146972656253.81471252441406225OK
疑问:Float和Double类型的包装类至少到对象16byte再加上float本身占用4byte,至少占用20字节与float相比差5倍的内存,大量使用的时候要注意.这里的String指的是同一个String,jvm会对它进行优化,放入常量池,而本身只保存一个引用,引用的大小是4byte.
[java对于数字类型Char,Integer,Short,Long都进行了优化]
那么如何计算一个对象的大小呢.
public MemObj(Integer a,Long b)
[当数字不在-127~128]
对象引用占4KB+空对象占8KB,Integer占4+16[创建],Long占4+16
* 预计占用52Kb
5.249168395996094 ==> 4.84906005859375025
* 实际一个对象占51Kb
[当数字在-127~128]
* 计算MemObj 因为对象过大,所以采用10W的对象
* 2.3214187622070312 ==> 1.92131042480468745
* 实际一个对象占20.146399999999999475712KB * 预计
* 对象引用占4KB+空对象占8KB,Integer占4,Long占4
* 总共20KB
注意使用数字时,能使用-127~128的,使用包装类型没问题,当不在这范围内时,最好使用基本类型,将会极大的优化存储.