java中测试对象内存消耗的实现结果混乱

java中测试对象内存消耗的实现结果混乱,java,eclipse,memory,Java,Eclipse,Memory,我使用下面的实现来测试java对象的内存消耗。 但当调用方法的for循环中的i限制从384到1694时,它将用法打印为104936b。 当上述i限制小于384时,它将使用打印为0B 为什么会这样 IDE:日食开普勒 java:1.5(当 java版本也已更改) 操作系统:Ubuntu 12.10 public static void main(String[] args) { Runtime runtime = Runtime.getRuntime(); long

我使用下面的实现来测试java对象的内存消耗。
但当调用方法的for循环中的i限制从384到1694时,它将用法打印为104936b
当上述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>();
    
        }
    }
    
    publicstaticvoidmain(字符串[]args){
    Runtime=Runtime.getRuntime();
    long totalStart=runtime.totalMemory();
    long start=runtime.freemory();
    SampleTester SampleTester=新的SampleTester();
    sampleTester.callingMethod();
    long totalEnd=runtime.totalMemory();
    long end=runtime.freemory();
    System.out.println(“用法[((“+totalEnd+”-“+end+”)-(“+totalStart+”-“+start+”)))”\t:“+((totalEnd-end)-(totalStart-start));
    }
    私有无效调用方法(){
    对于(int i=0;i<1694;i++){
    ArrayList ArrayList=新的ArrayList();
    }
    }
    

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

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

这就解释了“0”值(此优化或类似优化)

实际上,JVM并不总是这样做,但为了提高性能,它会让符合条件的对象在一段时间内处于未收集状态(因为频繁地执行GC可能会对性能造成同样的影响)

JVM决定应用哪种优化的时间和方式完全由实现定义,了解细节很少是有用的信息(因为您不能依赖于它,它可以随下一个版本而改变)


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

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

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

这就解释了“0”值(此优化或类似优化)

实际上,JVM并不总是这样做,但为了提高性能,它会让符合条件的对象在一段时间内处于未收集状态(因为频繁地执行GC可能会对性能造成同样的影响)

JVM决定应用哪种优化的时间和方式完全由实现定义,了解细节很少是有用的信息(因为您不能依赖于它,它可以随下一个版本而改变)

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

可能重复的