0

给我的一个方法,问它什么时候有资格进行垃圾收集,我的意思是在哪一行。我相信两者o都有oa资格进行垃圾收集。因为,它们被设置为null. 请纠正我,如果我错了。但是,问题是,它什么时候有资格获得gc,我的意思是在哪一行。?

public Object m() {
        Object o = new Float(3.14F);
        Object[] oa = new Object[1];
        oa[0] = o; /* Line 5 */
        o = null; /* Line 6 */
        oa[0] = null; /* Line 7 */
        return o; /* Line 8 */
    }

请任何人解释。?

4

5 回答 5

4

让我们看一下代码:

1)  o = new Float();  
2)  oa = new Object[];  
    at this point we have 2 objects.  
3) oa[0] = o;  
    at this point oa[0] holds the reference of o.  
4)  o = null;  
    o is still being referenced by oa[0]  
5)  oa[0] = null  
    o now has zero references.  
6)  return o;  
     o is null. 

第 7 行是 GC 资格发生的地方ooa在函数退出之前没有资格进行 GC。

一般来说,一个对象只有在没有引用时才有资格进行 GC。处理 a 时要非常小心,String因为有一个特殊的地方叫做字符串池。所以下面的代码:

void foo()  
{  
   String s = "foo";   
   s=null;  
   return s;  
}  

在任何时候都s不能保证在函数中符合条件。

来自评论的问题

一个问题,你说..oa 在函数退出之前没有资格进行 GC。但是,在返回 o 之前,oa 设置为 null 并且它也无处引用

回答:

oa 未设置为空。设置为 null 的是 oa[0] 处的对象(oa 的第一个索引)。如果该行是 oa = null 那将是正确的,并且不管 oa 中唯一的项目是否为 null,实际上并不会使包装器(在本例中为数组)为 null。类似于拥有一个 List 并清空其所有元素不会使 List 为空。

于 2012-10-31T19:47:48.310 回答
3

允许 Java 进行某些优化,因此仅考虑局部效应的优化 JIT 可以简化此代码以

public Object m() {
    //Object o =                    // o does not participate in any externally visible side-effect
    new Float(3.14F);               // Available for collection as soon as ctor finishes.
    //Object[] oa = new Object[1];  // Array ctors are known not to have side-effects, and oa does not participate in a side-effect or result that is visible outside the method.
    //oa[0] = o; /* Line 5 */       // Side-effect not visible.
    // o = null; /* Line 6 */       // Side-effect not visible.
    //oa[0] = null; /* Line 7 */
    //return o; /* Line 8 */        // Eliminated by inlining.
    return null;                    // Type-analysis proves that this method can only return null.
}

不要假设局部变量的赋值null实际上发生在长期存在的方法调用中。

于 2012-10-31T19:50:59.863 回答
1

当不再存在对该对象的引用时,垃圾收集是合格的,但重要的是要注意 GC 不能保证在那时运行,因此从技术上讲可以分配内存。

oa[0] 引用对象,因此当您在第 7 行将其设置为 null 时,不再存在对该对象的引用,因此它符合 GC 条件。

正如评论所指出的,数组本身 oa 仍然存在,直到方法完成执行,即在第 8 行执行之后。它在方法 m() 的生命周期中是本地的,因此当 m() 从执行返回时,它将符合 GC 条件。

于 2012-10-31T19:45:24.893 回答
0

请纠正我,如果我错了。但是,问题是,它什么时候有资格获得 gc,我的意思是在哪一行。?

这个问题是荒谬的或基于过度简化的垃圾收集模型。垃圾收集器在运行时对可用表示进行操作,这意味着从包括寄存器、堆栈和全局变量在内的全局根跟踪可达性。与高级源代码没有对应关系,因此询问行号是没有意义的。实际上,编译器会在 GC 运行之前将您的代码弄得面目全非。

于 2013-01-06T11:16:59.737 回答
-1

AFAIK,Java 使用 Mark-And-Sweep 算法。GC 反复在堆上的单独线程中运行。

如果某个引用变量(或对象)超出范围,则将其标记为删除并在适当时清除(或覆盖)。

此外,每当变量设置为 null 时,即当引用计数对象变得无法被静态引用和其他线程访问时,即当它的引用不再存在时,它会再次标记为删除。

代码中的第 7 行将标记为删除。

于 2012-10-31T19:46:05.330 回答