Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 引用队列中的PhantomReference是否阻止PhantomReference成为GC';D_Java - Fatal编程技术网

Java 引用队列中的PhantomReference是否阻止PhantomReference成为GC';D

Java 引用队列中的PhantomReference是否阻止PhantomReference成为GC';D,java,Java,我正在使用LWJGL库,不幸的是,每当场景图中的节点需要死亡时,我需要自己释放纹理/vbo缓冲区,我甚至不能使用finalize()方法来完成此操作,因为我不能保证它将在opengl libs期望的同一线程中执行 所以我用的是幻影参考。在我的场景图节点中,我将其放入构造函数中: phantomReference = new ScenePhantomReference(this, Game.phantomReferenceQueue); Game.phantomReferenceList.add(

我正在使用LWJGL库,不幸的是,每当场景图中的节点需要死亡时,我需要自己释放纹理/vbo缓冲区,我甚至不能使用finalize()方法来完成此操作,因为我不能保证它将在opengl libs期望的同一线程中执行

所以我用的是幻影参考。在我的场景图节点中,我将其放入构造函数中:

phantomReference = new ScenePhantomReference(this, Game.phantomReferenceQueue);
Game.phantomReferenceList.add(phantomReference);
正如您在第二行中看到的,我已将phantomReference添加到main类的列表中。我的逻辑是,当节点被解除引用时,phantomReference不会被垃圾收集,因为在主类中仍然有一个引用

是否需要将其添加到这样的列表中?或者它会不会从GC中保留(可能Game.phantomReferenceQueue会保留对它的引用?)


这是一个很难测试的问题,我可以删除列表,但是GC可能只是处理在phantomReference之前被监视的对象,并使其看起来像列表是多余的,而实际上并非如此。我会怀疑任何不同的虚拟机实现或版本可能会以相反的方式来实现它。

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

然而,我确实读过,也读过,等等

  • “是否需要将其添加到这样的列表中?[…](可能Game.phantomReferenceQueue会保留对它的引用?):根据javadoc页面:“引用队列,在检测到适当的可达性更改后,垃圾收集器会将注册的引用对象追加到该队列中。”。所以我认为不,您不应该将其添加到列表中,因为队列将自动由垃圾收集器添加它
  • 我想你必须重新措辞一下你的问题——我不明白这个清单是为了什么,也就是说,我不明白最后一段。但是如果您使用列表是为了知道phantomReference是否是gc’ed,那么不,您根本不应该使用列表,这就是ReferenceQueue的用途。此外,该列表将防止phantomReference被gc’ed 编辑:再次阅读文章标题。回答标题问题:否,因为PhantomReference在gc'ed之后进入ReferenceQueue,因此根据定义,它不能停止gc'ed。引用第一个链接:“这种引用的唯一用途[注:他指的是PhantomReference]跟踪它何时进入引用队列,因为此时您知道它指向的对象已死亡”

    编辑#2:我还认为您的代码是错误的,您应该初始化幻影引用,如下所示(参见一个简单的示例):


    其中
    scene
    是代码中的
    ScenePhantomReference
    (即,您应该重构代码,使
    ScenePhantomReference
    成为名称,例如
    scene
    ,您将其实例化为
    scene
    ,然后使用上面的行获取该对象的
    幻影引用的句柄)。
    
    如果您不将
    PhantomReference
    添加到
    列表
    ,则不会引用
    PhantomReference
    对象,因此它会立即被GC'd,并且永远不会进入队列。

    我使用了它们,根据经验,我可以说您需要维护一个引用,以防止它被GC'd。我做过一次,并使用IdentityHashMap作为一个集合(值总是一个虚拟对象)。这比List/HashMap快。编辑:下面是代码:这是在:已注册的引用对象与其队列之间的关系是单边的。也就是说,队列不跟踪已注册的引用。如果已注册的引用本身无法访问,则它将永远不会排队。使用引用对象的程序负责确保对象重新访问只要程序对其引用对象感兴趣,就可以访问main”。
    PhantomReference scenePhantomRef = new PhantomReference(scene, phantomQueue);