在ReferenceQueue中的PhantomReference是否会阻止PhantomReference进行GC?

Cal*_*lum 11 java

我正在使用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实现或版本都可能决定反过来这样做.

Luc*_*lis 4

免责声明:我从未使用过 PhantomReference。

但是,我确实阅读了这篇文章这个 javadoc 页面,等等

  1. “是否需要将其添加到这样的列表中?[...](也许 Game.phantomReferenceQueue 保留对它的引用?)”:根据 javadoc 页面:“引用队列,注册的引用对象由检测到适当的可达性变化后的垃圾收集器。” 所以我相信不,你不应该将其添加到列表中,因为队列会自动由垃圾收集器添加它。
  2. 我认为你必须重新表述你的问题 - 我不明白列表的用途,即我不明白最后一段。但是,如果您使用列表是为了知道 phantomReference 是否被 gc'ed,那么不,您根本不应该使用列表,这就是 ReferenceQueue 的用途。此外,List 将防止 phantomReference 被 gc'ed!

编辑:再次阅读您的帖子标题。单独回答标题问题:不,因为 PhantomReference 在被 gc'ed 之后进入 ReferenceQueue - 因此根据定义,它不能被阻止被 gc'ed。引用第一个链接:“这种引用的唯一用途[注意:他的意思是 PhantomReference] 是跟踪它何时排队到 ReferenceQueue 中,因为此时您知道它指向的对象已死亡”

编辑#2:我还认为您的代码是错误的,因为您应该按如下方式初始化幻像引用(请参阅此处的简单示例):

PhantomReference scenePhantomRef = new PhantomReference(scene, phantomQueue);
Run Code Online (Sandbox Code Playgroud)

其中sceneScenePhantomReference代码中的 (即,您应该重构代码,使其ScenePhantomReference名称为 例如Scene,将其实例化为scene,然后使用上面的行获取PhantomReference该对象的句柄)。