любой способ сказать, если метод закончился или локальный в методе больше не используется? - PullRequest
0 голосов
/ 26 августа 2018

Мне нужно какое-то решение, которое поможет мне определить некоторые методы в случае, подобном этому:

void myMethod(...)
{
    MyObject obj = new MyObject();
    // do stuff
}

если этот метод завершился или obj недоступен (что будет означать, что метод завершился).

Я пишу небольшой Java-агент, и я надеюсь на какую-то технику, которая либо сообщит мне наверняка, что этот метод завершен, либо obj недоступен ... В моем случае раздел "делать вещи" не использует объект вообще. Он не передает эту переменную в другое место или добавляет ее в какую-либо коллекцию.

Я знаю, что с помощью Weak / Soft / Phantom-References я могу частично достичь этого. Если вызывается GC, то имея:

void myMethod(...)
{
    MyObject obj = new MyObject();
    WeakReference objReference = new WeakReference(obj);

    // do stuff
}

Я всегда могу проверить в другом месте:

    if (objReference.get() == null) ...

Тем не менее, это возможно только в том случае, если произошел GC.

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

Я не хочу полагаться на ASM - и добавлять оболочку try-finally для всех этих методов. Надеялся на более тонкое, справочное решение.

1 Ответ

0 голосов
/ 26 августа 2018

Единственный надежный способ сделать это ... что я могу придумать ... это использовать обратные вызовы / слушатели;Например,

public MyClass

    void myMethod(Function<MyClass, Void> onCompletion) {
        try {
            // Do stuff
        } finally {
            onCompletion.apply(this);
        }
    }

Вы также можете реализовать это, используя MethodHandles.tryFinally, чтобы создать дескрипторы методов для вашего метода, которые реализуют обратный вызов, оборачивая методы.

Все, что основано на типах Reference, неявно зависит от сборки мусора.Это будет дорого, и вы будете иметь небольшой контроль над получением уведомлений.


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

AFAIK, нет, нет.И JVM / JIT не делают то, что вы предположили;то есть они не помечают «очевидный» локальный объект для финализации или сбора перед обычным циклом GC.

Почему бы и нет?Потому что это сделало бы приложения медленнее, если бы это произошло.Единственное преимущество заключается в том, что финализация / обработка ссылок может произойти раньше, но для хорошо написанного приложения это не имеет значения.Хорошо написанная программа не должна заботиться о , когда происходит завершение / обработка ссылок, так как время явно не гарантируется спецификациями.

И оказывается, что escape-анализ тоже не помогает:

Теперь я знаю, что JIT может корректировать таблицы, которые сообщают GC, что еще находится в области видимости (см. Комментарий Хольгера; например, finalize () вызывается для сильно достижимого объекта в Java 8 ).Но это не меняет последовательность инструкций метода.Только GC обращает внимание на эту информацию ... , пока GC работает .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...