Предоставляет ли PhantomReference в ReferenceQueue прекращение действия PhantomReference из GC'd?

Я использую библиотеки LWJGL, и, к сожалению, мне нужно освобождать буферы текстур /vbo, когда node в моем графике сцены должен умереть, я даже не могу использовать метод finalize() для этого, поскольку я не может гарантировать, что он будет выполнен в том же потоке, который ожидают ему opengl libs.

Итак, я использую PhantomReferences. В моих узлах графика сцены я поместил это в конструктор:

phantomReference = new ScenePhantomReference(this, Game.phantomReferenceQueue);
Game.phantomReferenceList.add(phantomReference);

Как вы можете видеть во второй строке, я добавил phantomReference в список в основном классе. Моя логика заключается в том, что когда node становится разыменованным, phantomReference не будет собирать мусор с ним, поскольку в основном классе есть ссылка.

Добавляет ли он список, который вам нужен? Или он будет спасен от GC (возможно, Game.phantomReferenceQueue сохраняет ссылку на него?).

Это одна из проблем для проверки, я мог просто удалить список, но GC мог просто обработать объект, который просматривается перед phantomReference, и сделать его похожим на список избыточным, когда это действительно не так. Я был бы параноидальным, что любая другая реализация или версия VM может решить сделать это наоборот.

Ответ 1

Отказ от ответственности: я никогда не использовал PhantomReference.

Однако я прочитал эту статью и эту страницу javadoc, и поэтому

  • "Является ли это добавлением к списку, который вам нужен? [...] (возможно, Game.phantomReferenceQueue сохраняет ссылку на него?)": Согласно странице javadoc: "Очереди ссылок, к которым относятся зарегистрированные ссылочные объекты добавляется сборщиком мусора после обнаружения соответствующих изменений достижимости". Поэтому я считаю, что нет, вы не должны добавлять его в список, так как очередь автоматически добавит его сборщиком мусора.
  • Я думаю, вам нужно немного перефразировать ваш вопрос - я не понимаю, что такое List, т.е. я не понимаю последний абзац. Но если вы используете список, чтобы узнать, является ли phantomReference gc'ed, то нет, вы не должны использовать список вообще, что для этого есть ReferenceQueue. Кроме того, Список предотвратит gn'spherement of the gc'ed!

Изменить: снова прочитайте заголовок своего сообщения. Ответ на вопрос заголовка сам по себе: Нет, потому что PhantomReference входит в ReferenceQueue после того, как он был gc'ed, поэтому по определению он не может быть остановлен от gc'ed. Чтобы процитировать первую ссылку: "Единственное использование для такой ссылки [примечание: он означает, что PhantomReference] отслеживает, когда оно попадает в ссылку ReferenceQueue, так как в этот момент вы знаете, что объект, на который он указал, мертв"

Изменить # 2: Я также считаю, что ваш код неверен в том, что вы должны инициализировать ссылку phantom следующим образом (см. простой пример здесь):

PhantomReference scenePhantomRef = new PhantomReference(scene, phantomQueue);

где scene является ScenePhantomReference из вашего кода (т.е. вы должны реорганизовать свой код так, чтобы ScenePhantomReference называлось именем scene), вы создаете его как scene, а затем используете строку выше, чтобы получить дескриптор для PhantomReference для этого объекта).

Ответ 2

PhantomReference объект добавляется в очередь, когда объект ID объекта ссылки GC'd, а не PhantomReference. Если вы не добавляете PhantomReference в List, ссылка на объект PhantomReference отсутствует и, следовательно, она немедленно вызывается GC и не входит в очередь.