在java包装类中使用new运算符的内存分配有什么不同吗?

时间:2011-03-15 11:00:36

标签: java memory-management

在java包装类中使用new opeartor的内存分配是否存在差异?

对于班级来说,

public class TestClass {
    Integer r=9;
}

在32位JVM中分配的内存大小为5152字节

至于

public class TestClass1 {

    Integer i=new Integer(1);

}

内存大小为32个字节。

为什么类TestClass1的内存分配较少?

5 个答案:

答案 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时,缓存也会被初始化。