我正在使用LWJGL库,不幸的是,每当我的场景图中的一个节点需要死时,我就需要释放纹理/ vbo缓冲区,我甚至不能使用finalize()方法来执行此操作,因为我可以' t保证它将在opengl lib期望的相同线程中执行。
所以我正在使用PhantomReferences。在我的场景图节点中,我将它放在构造函数中:
phantomReference = new ScenePhantomReference(this, Game.phantomReferenceQueue);
Game.phantomReferenceList.add(phantomReference);
正如您在第二行中所看到的,我已将phantomReference添加到主类中的列表中。我的逻辑是,当节点被解除引用时,phantomReference不会被垃圾收集,因为主类中仍有引用。
是否将其添加到需要的列表中?或者它是否会从GC中幸免(可能Game.phantomReferenceQueue会保留对它的引用?)。
这个测试很痛苦,我可以删除列表,但GC可能只是在phantomReference之前处理正在观察的对象,并使其看起来像列表是多余的,而实际上并非如此。我是偏执狂,任何不同的虚拟机实现或版本都可能决定反过来。
答案 0 :(得分:4)
免责声明:我从未使用过PhantomReference。
但是,我确实阅读了this article和this javadoc page,所以
编辑:再次阅读帖子的标题。单独回答标题问题:不,因为PhantomReference在gc'ed之后进入ReferenceQueue - 所以根据定义它不能被停止为gc'ed。引用第一个链接:“这种引用的唯一用途[注意:他的意思是PhantomReference]跟踪它何时被引入ReferenceQueue,因为那时你知道它指向的对象已经死了”
编辑#2:我还认为你的代码是错误的,你应该按如下方式初始化幻像引用(参见一个简单的例子here):
PhantomReference scenePhantomRef = new PhantomReference(scene, phantomQueue);
其中scene
是您代码中的ScenePhantomReference
(即您应该重构代码,以便ScenePhantomReference
是名称,例如Scene
,您将其实例化为scene
然后使用上面的行来获取该对象PhantomReference
的句柄。
答案 1 :(得分:0)
PhantomReference
对象被添加到队列中,而不是PhantomReference
本身。
如果您没有向PhantomReference
添加List
,则不会引用PhantomReference
对象,因此它会立即进行GC并且永远不会进入队列。