在java中为GC创建在循环内创建的对象

时间:2014-04-07 01:25:12

标签: java memory-management garbage-collection

Object ready for Garbage collection, Java表示只有在函数结束时,对象才可用于gc。因此,如果我在循环内创建对象,如何在函数终止之前确保它们可用于gc e.g

void foo{
  for(int i = 0; i < 10000; i++){
    Object o = new Object();

    /*some operation*/
  }
}

由于在循环中创建了许多对象,我希望在函数结束之前对象可用于gc。

使用后将其设为null使其可用于gc,或者它具有与上述相同的效果。例如

   void foo{
      for(int i = 0; i < 10000; i++){
        Object o = new Object();

        /*some operation*/
        o = null;
  }
}

2 个答案:

答案 0 :(得分:2)

看看这个测试:

public long test(){
    long result = 0;
    for(int i=0;i<30_000;++i){
        for(int j=0;j<30_000;++j){
            Object obj1 = new Object();
            result = result ^ System.identityHashCode(obj1);
        }
    }
    return result;
}

我在这里为这个函数创建大约879MB的数据(16个字节java.java.Object乘以30_000然后再次30_000)。

我正在运行它:

java -Xms40m -Xmx40m -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails TestFunc

只给它40MB的堆,意味着如果Java在for循环没有完成之前无法重新收集内存,它应该崩溃,但这不会发生。

相反,你会看到很多像这样的行:

[GC [PSYoungGen: 11088K->368K(13312K)] 11096K->376K(40960K), 0.0013320 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

这是Young Generation中的“次要”垃圾收集调用。 因此,如果你有内存压力,GC可以并且实际上会被触发,如果你还没有完成循环也没关系。如果不需要对象,则会重新收集它们。

答案 1 :(得分:2)

  

对象已准备好进行垃圾收集,Java表示只有在函数结束时,对象才可用于gc。

不,不。我写了那个答案,并没有说出任何这样的话。

它实际上说的是堆栈插槽一直存在,直到函数退出。对于代码,除了最后一个之外在循环内创建的所有对象在创建下一个对象后立即变为未引用,因为同一堆栈槽中的先前引用将被覆盖。请参阅@Thilo的评论,该评论正是如此。