Сбор мусора и отражение

Мне интересно, как работает сборка мусора, когда у вас есть класс с отражением, используемый для получения значений некоторых полей. Как 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);
        }
    }
}

С уважением,
Крис


person Chris Dennett    schedule 22.06.2011    source источник
comment
Интересный вопрос. Было ли это вдохновлено каким-то встроенным Java-приложением?   -  person James T Snell    schedule 22.06.2011
comment
Не могли бы вы включить фрагмент кода, чтобы уточнить, что вы подразумеваете под классом с отражением, используемым для получения значений некоторых полей?   -  person Ben Burns    schedule 22.06.2011
comment
На самом деле, я работаю над тестом сетевой среды, и доступ к некоторым полям осуществляется путем отражения. Интересно, как отражение влияет на использование памяти, возможно, с сохранением объектов JVM, в которых он не уверен.   -  person Chris Dennett    schedule 22.06.2011
comment
Отражение всегда добавляет дополнительные накладные расходы. Например, если вы выполняете вызов метода с использованием отражения, вы должны сначала получить ссылку на объект метода и т. д. Это означает, что вы создаете объекты и выполняете несколько других вызовов (и обычно некоторую условную логику) просто для выполнения один вызов метода. Вообще говоря, вы предпочтете этот подход, когда его гибкость перевешивает недостаток производительности.   -  person Ben Burns    schedule 22.06.2011
comment
Согласовано. Однако я делаю некоторые сложные вещи, связанные с состояниями и почтением через прокси. Почти как более простая версия инъекции.   -  person Chris Dennett    schedule 22.06.2011


Ответы (3)


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

person Robin    schedule 22.06.2011

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

person Peter Lawrey    schedule 22.06.2011

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

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

person Trent Gray-Donald    schedule 24.06.2011