Сбор мусора и отражение - PullRequest
7 голосов
/ 22 июня 2011

Мне интересно, как работает сборка мусора, когда у вас есть класс с отражением, используемый для получения некоторых значений полей. Как JVM осознает, что ссылки на значения в этих полях доступны и поэтому не пригодны для сбора мусора в настоящий момент, когда для доступа к ним не используется синтаксис формального языка?

Небольшой фрагмент, указывающий на проблему (хотя рефлексия здесь переоценена):

/**
 *
 */

import java.lang.reflect.Field;

public class B {
    protected B previous = null, next = null;

    /**
     *
     */
    public B(B from) {
        this.previous = from;
    }

    public void transition(B to) {
        this.next = to;
    }

    public B next() {
        try {
            Field f = getClass().getField("next");
            f.setAccessible(true);
            try {
                return (B)f.get(this);
            } finally {
                f.setAccessible(false);
            }
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
    }

    public B previous() {
        try {
            Field f = getClass().getField("previous");
            f.setAccessible(true);
            try {
                return (B)f.get(this);
            } finally {
                f.setAccessible(false);
            }
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
    }
}

Ура,
Chris

Ответы [ 3 ]

10 голосов
/ 22 июня 2011

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

5 голосов
/ 22 июня 2011

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

1 голос
/ 24 июня 2011

Это немного странный тестовый пример: вы используете отражение для доступа к «этому». По определению «this» является действующим при использовании в методе экземпляра объявленного класса, поэтому не будет GCed.

Но, более конкретно, рефлексия просто позволяет вам манипулировать полями и т. Д. В объектах, на которые у вас уже есть ссылки. Это ключ - если вы можете дать Reflect экземпляр для изучения, у вас явно есть ссылка на объект, поэтому он остается живым.

...