在java包装类中使用new opeartor的内存分配是否存在差异?
对于班级来说,
public class TestClass {
Integer r=9;
}
在32位JVM中分配的内存大小为5152字节
至于
public class TestClass1 {
Integer i=new Integer(1);
}
内存大小为32个字节。
为什么类TestClass1的内存分配较少?
答案 0 :(得分:2)
该行:
Integer r = 9;
实际上变成了:
Integer r = Integer.valueOf(9);
由于自动装箱,它会检索缓存的Integer对象。如果您在Boxing Conversions上检查JLS Section 5.1.7,则表明缓存了-128到127之间的整数值。实际上,第一次调用Integer.valueOf()
(包括自动装箱事件)将初始化缓存,这可能会占用不同的内存占用量。
答案 1 :(得分:1)
你是如何衡量这一点的?
在我看来,JVM完全有权在TestClass1中优化掉Integer,因为它从未使用过,只留下对空类的引用
答案 2 :(得分:1)
Integer.valueOf
并不总是创建新对象。这就是
Integer r = 9;
答案 3 :(得分:0)
public class Sizer {
public static void main(String [] args) throws Exception {
Runtime r = Runtime.getRuntime();
// Pre-instantiate variables
long memoryBefore = 0;
long memoryAfter = 0;
int loops = 10;
runGC(r, loops);
memoryBefore = getMemoryUsage(r);
// Long lo = new Long(1);
TestClass in = new TestClass();
runGC(r, loops);
memoryAfter = getMemoryUsage(r);
System.out.println("Diff in size is " + (memoryAfter - memoryBefore));
}
public static void runGC(Runtime r, int loops) throws Exception {
for(int i=0; i<loops; i++) {
r.gc();
Thread.sleep(2000);
}
}
public static long getMemoryUsage(Runtime r) throws Exception {
long usedMemory = r.totalMemory() - r.freeMemory();
System.out.println("Memory Usage: " + usedMemory);
return usedMemory;
}
}
答案 4 :(得分:0)
问:为什么TestClass1类的内存分配较少?
正如krock已经提到的那样
Integer i = 9;
将成为
Integer i = Integer.valueOf(9);
此指令导致必须先初始化缓存,然后才能使用它。
缓存包含-128到127之间的值,这给出了必须初始化的255个值(new Integer(i)
)。而这导致如此大的内存使用量。
恢复指令
i = new Interger(9);
- 将创建一个Integer对象,i = 9;
- 将创建至少255个Integer对象和一个数组。
FYI:缓存初始化不依赖于盒装值。当装箱值低于-128且大于127时,缓存也会被初始化。