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
基本类型
数据类型 预计占存 实际占存 结果
int 3.814697265625 3.81471252441406225 OK
short 1.9073486328125 1.90736389160156245 OK
long 7.62939453125 7.62940979003906225 OK
float 4.214820861816406 3.81471252441406225 OK
double 7.62939453125 7.62940979003906225 OK
char 1.9073486328125 1.90736389160156245 OK
包装类型
数据类型 预计占存 实际占存 结果
Integer[存储优化] 3.814697265625 3.81471252441406225 OK
Short[存储优化] 3.814697265625 3.81471252441406225 OK
Long[存储优化] 3.814697265625 3.81471252441406225 OK
Float 19.073486328125 18.99338531494140625 不理想
Double 19.073486328125 18.99338531494140625 不理想
Object 11.444091796875 11.27165222167968725 不理想
String 3.814697265625 3.81471252441406225 OK
Char[存储优化] 3.814697265625 3.81471252441406225 OK

疑问: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的,使用包装类型没问题,当不在这范围内时,最好使用基本类型,将会极大的优化存储.

你可能感兴趣的:(jvm)