Будет ли это сборка мусора в JVM? - PullRequest
4 голосов
/ 17 июня 2010

Я запускаю следующий код каждые две минуты через таймер:

object = new CustomObject(this);

Потенциально, это много объектов, которые создаются, и много объектов, которые перезаписываются. Получают ли перезаписанные объекты сборщик мусора, даже если во вновь созданном объекте используется ссылка на себя?

Я использую JDK 1.6.0_13.

Спасибо за помощь.

Ответы [ 4 ]

3 голосов
/ 17 июня 2010

Нам нужно знать, что происходит внутри конструктора, чтобы полностью ответить на вопрос.

Но обычно, пока ничто не сохраняет ссылку на старый объект при создании нового, он будет доступен для сборки мусора, даже если старый объект используется в процессе создания новый.

Например:

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 голосов
/ 17 июня 2010

Java использует сборщик мусора "mark and sweep". По сути, это означает: если он доступен вашим рабочим кодом, он не подходит для сборки мусора, в противном случае это так.

1 голос
/ 17 июня 2010

Это зависит от того, что вы делаете с объектом в конструкторе. Если вы сохраните ссылки на него во вновь созданном объекте, это не позволит сборщику мусора освободить память.

Пример ниже демонстрирует это:

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 любой достижимый объект из "живого" объекта не будет кандидатом на сборку мусора.

0 голосов
/ 17 июня 2010

Перезаписанных объектов нет. object просто привязан к новому экземпляру Object. Пока нет никаких дополнительных ссылок на ранее существующий экземпляр, он будет удален GC в какой-то момент. Не имеет значения, хранит ли этот ребенок ссылку на своего родителя. Как только он станет недоступным, он будет помечен для GC.

Полагаю, это не совсем java.lang.Object, что вы имеете в виду здесь.

...