我正在使用LWJGL库,不幸的是,每当我的场景图中的节点需要死时,我都需要释放纹理/ vbo缓冲区,我甚至无法使用finalize()方法来执行此操作,因为我无法保证它将在opengl libs期望的同一个线程中执行.
所以我正在使用PhantomReferences.在我的场景图节点中,我将它放在构造函数中:
phantomReference = new ScenePhantomReference(this, Game.phantomReferenceQueue);
Game.phantomReferenceList.add(phantomReference);
Run Code Online (Sandbox Code Playgroud)
正如您在第二行中看到的,我已将phantomReference添加到主类中的列表中.我的逻辑是,当节点被解除引用时,phantomReference将不会被垃圾收集,因为在主类中仍然存在引用.
将它添加到需要的列表中吗?或者它是否会从GC中幸免(可能Game.phantomReferenceQueue会保留对它的引用?).
这个很难测试,我可以删除列表,但GC可能只是在phantomReference之前处理正在观察的对象,并使它看起来像列表是多余的,当它真的没有.我很偏执,任何不同的VM实现或版本都可能决定反过来这样做.
免责声明:我从未使用过 PhantomReference。
但是,我确实阅读了这篇文章和这个 javadoc 页面,等等
编辑:再次阅读您的帖子标题。单独回答标题问题:不,因为 PhantomReference 在被 gc'ed 之后进入 ReferenceQueue - 因此根据定义,它不能被阻止被 gc'ed。引用第一个链接:“这种引用的唯一用途[注意:他的意思是 PhantomReference] 是跟踪它何时排队到 ReferenceQueue 中,因为此时您知道它指向的对象已死亡”
编辑#2:我还认为您的代码是错误的,因为您应该按如下方式初始化幻像引用(请参阅此处的简单示例):
PhantomReference scenePhantomRef = new PhantomReference(scene, phantomQueue);
Run Code Online (Sandbox Code Playgroud)
其中scene是ScenePhantomReference代码中的 (即,您应该重构代码,使其ScenePhantomReference名称为 例如Scene,将其实例化为scene,然后使用上面的行获取PhantomReference该对象的句柄)。