1

我使用下面的实现来测试 java 对象的内存消耗。
但是当调用方法的 for 循环中的 i 限制为 384 到 1694 时,它会将使用情况打印为104936 B。当上述 i 限制小于 384 时,
它将使用情况打印为0B 。

为什么是这样?

  • IDE:日食开普勒
  • java : 1.5(当java版本也改变时,这会有所不同)
  • 操作系统:Ubuntu 12.10

    public static void main(String[] args) {
    
        Runtime runtime     = Runtime.getRuntime();
    
        long totalStart     = runtime.totalMemory();
        long start          = runtime.freeMemory();
    
        SampleTester sampleTester = new SampleTester();
        sampleTester.callingMethod();
    
        long totalEnd       = runtime.totalMemory();
        long end            = runtime.freeMemory();
    
        System.out.println("Usage [(("+totalEnd+"-"+end+") - ("+totalStart+"-"+start+"))] \t: " + ((totalEnd-end) - (totalStart-start)));
    
    }
    
    private void callingMethod(){
    
        for(int i = 0;  i < 1694; i++){
    
            ArrayList<String> arrayList = new ArrayList<String>();
    
        }
    }
    
4

1 回答 1

4

ArrayList当当前循环迭代结束时,您创建的每个都立即符合 GC 条件。

所以理论上JVM可以ArrayList在上一次迭代之前占用的空间中分配每个,并且只需要一个“槽”,当最后一次迭代结束并且方法存在时,它会被丢弃。

这解释了“0”值(这个或类似的优化)。

在实践中,JVM 并不总是这样做,而是会在一段时间内不收集符合条件的对象以提高性能(因为过于频繁地执行 GC 对性能同样不利)。

JVM何时以及如何决定应用哪种优化完全是实现定义的,知道非常详细的信息很少有用(因为你不能依赖它,它可能会随着下一个版本而改变)。

因此,如果您想了解n 个 对象需要多少内存ArrayList,请确保您 在检查当前使用的内存时,每一个实际上都是可访问的,因此不符合垃圾收集的条件。

于 2013-10-17T12:37:13.283 回答