【问题标题】:Will this be garbage collected in JVM?这会在 JVM 中被垃圾收集吗?
【发布时间】:2010-06-17 13:59:56
【问题描述】:

我通过计时器每两分钟运行一次以下代码:

object = new CustomObject(this);

这可能是创建了很多对象并覆盖了很多对象。被覆盖的对象是否会被垃圾回收,即使在新创建的对象中使用了对自身的引用?

我使用的是 JDK 1.6.0_13。

感谢您的帮助。

【问题讨论】:

    标签: java memory-leaks garbage-collection


    【解决方案1】:

    我们需要知道构造函数内部发生了什么才能完全回答这个问题。

    但一般情况下,只要在创建新对象时没有保留对旧对象的引用,它就可以用于垃圾回收,即使在处理过程中使用了旧对象也是如此创建新的。

    例如:

    class Foo {
        private String name;
    
        Foo() {
            this.name = null;
        }
    
        Foo(Foo f) {
            this.name = f.name;
        }
    
        public void setName(String n) {
            this.name = n;
        }
    
        public Foo spawn() {
            return new Foo(this);
        }
    }
    

    当新的Foo被构造时,这不会保留对旧Foo的引用,所以旧的Foo可以被GC'd:

    Foo f;
    
    f = new Foo(); // The first Foo
    f.setName("Bar");
    
    while (/* some condition */) {
        // Periodically create new ones
        f = f.spawn();
    }
    

    而如果 Foo 看起来像这样:

    class Foo {
        private Foo parent;
    
        Foo() {
            this.parent = null;
        }
    
        Foo(Foo f) {
            this.parent = f;
        }
    
        public Foo spawn() {
            return new Foo(this);
        }
    }
    

    ...那么每个新生成的Foo 都会引用之前的Foo 并且没有一个可用于GC。

    【讨论】:

    • 谢谢,这清除了它。我不知道保留对活动对象的引用是否会允许其他对象被垃圾收集。
    【解决方案2】:

    Java 使用“标记和清除”垃圾收集器。基本上这意味着:如果您的运行代码可以访问它,则它不符合垃圾收集的条件,否则它是。

    【讨论】:

    • java已经有一段时间没有使用mark和sweep作为主要的gc了。它现在使用几代人。不是 GC 的 方法 真的很重要。 java 在规范中保证,如果它是可达的,它不会被 GC'ed,否则它是/(可能是)。
    • @james:方法很重要:“可达”标准只能通过标记和扫描或类似方法(java 确实使用)来满足,而不是通过引用计数。
    【解决方案3】:

    这取决于你在构造函数中对对象做了什么。如果在新创建的对象中保留对它的引用,这将阻止垃圾收集器回收内存。

    下面的例子证明了这一点:

    class Inner {
        public Inner() {
                this.ref = null;
        }
    
        public Inner(Inner ref) {
                this.ref = ref;
        }
    
        Inner ref;
    }
    
    class Test {
        public static void main(String [] args) {
                Inner x = new Inner();
    
                while(1==1) {
                        x = new Inner(x);
                }
        }
    }
    

    在 java 中,任何来自“活动”对象的可达对象将成为垃圾回收的候选对象。

    【讨论】:

      【解决方案4】:

      没有被覆盖的对象。 object 只是绑定到一个新的 Object 实例。只要没有对预先存在的实例的额外引用,它就会在某个时候被 GC 删除。该孩子是否保留对其父母的引用并不重要。一旦它变得无法访问,它将被标记为 GC。

      我猜你的意思不是真的java.lang.Object

      【讨论】:

        猜你喜欢
        • 2019-01-14
        • 1970-01-01
        • 1970-01-01
        • 2023-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-08
        相关资源
        最近更新 更多