Java垃圾收集和空

问题描述:

我的代码下面的一段:Java垃圾收集和空

List<String> list = new ArrayList<String>(); 
    // WeakReference<List> wr = new WeakReference<List>(list); 
    System.out.println(" before tot memory... " + Runtime.getRuntime().totalMemory()); 
    System.out.println(" before free memory... " + Runtime.getRuntime().freeMemory()); 
    for(int i =0; i<100; i++) 
    list.add(new String("hello")); 
    //System.gc(); 
    list = null; //forcefully end its life expectancy 
    System.out.println(" after tot memory... " + Runtime.getRuntime().totalMemory()); 
    System.out.println(" after free memory... " + Runtime.getRuntime().freeMemory()); 
    System.out.println(" after memory used ... " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())); 
    // System.out.println(" weak reference " + wr.get()); 

当我运行上面的代码,我可以看到的空闲内存是361064(在我的系统,但是这个值可能不同)

但是当我用System.gc()和注释列表= null运行上面的代码时,我可以看到我的可用内存即将到来(在这种情况下为160944)小于上述测试用例。在这两种情况下,对象都从内存中移除,但为什么这些值是不同的。

+1

'new String(“hello”)'创建两个对象。这个构造函数不应该被使用。尝试'list.add(“hello”)' – 2012-04-06 08:34:43

+0

@ajozwik我不会说'从来没有'。它有一些有效的用例。这就是它存在的原因。 – EJP 2012-04-06 09:45:22

list = null;取消任何引用将自动导致垃圾回收。当您对此行发表评论时,参考列表仍处于活动状态,则即使您致电System.gc()它也不会被垃圾收集。

当您明确呼叫gc()时,已被取消的引用或超出范围的引用仅被垃圾收集。

+0

如果是这样的话,System.gc()的用法是什么。在这种情况下,它可以被真正使用:)另外,如果list = null注释并运行应用程序,System.gc()调用会执行什么操作,因为它可以释放或释放一些东西 – UVM 2012-04-06 07:08:20

+0

@UNNI gc()将释放所有那些引用被取消或超出范围。它永远不会清除那些活动的引用。 – 2012-04-06 07:16:28

+0

在上面的测试用例中,当您仅使用System.gc()运行时,它释放了一些内存或某个“值”。在这种情况下,释放该值的原因是该列表仍处于活动状态,它不会被放弃。 – UVM 2012-04-06 07:25:25

GC通过查看内存中的所有对象以查找程序中的任何objects which are no longer being referenced。这些未使用的对象可以被删除,以便为新的内存对象腾出空间。

因此,如果任何对象仍然被转介,即使您拨打System.gc()也无法收集垃圾。如果可以在代码中引用对象,如何收集垃圾对象?

通过调用list = null,由list变量引用的对象不能再被引用,因此它有资格获取垃圾回收。