问题标签 [phantom-reference]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
36 浏览

java - GC 不会通过 Phantom References 收集类的内部字段

当引用对象是类中的字段时,我遇到了幻像引用的问题。当类对象设置为 null 时,GC 不会自动收集字段

控制器.java

Collector.java:我有一个收集器,它将一个对象注册到引用队列并在收集时打印它。

引用.java

测试是一个空类。我可以看到当 Reffered 对象设置为 null 时,不收集 Refferred 类中的“下一个”字段。换句话说,当“strong”设置为空时,不收集“next”。我假设“next”将由 GC 自动收集,因为当“strong”设置为 null 时不再引用“next”。但是,当“strong.next”设置为null时,“next”就如我们所想的那样被收集。为什么strong设置为null时不会自动收集“next”?

0 投票
2 回答
1874 浏览

java - 如何使用 PhantomReference 作为 finalize() 替换

PhantomReference的 Javadoc 8 状态:

幻影引用最常用于以比 Java 终结机制更灵活的方式调度事前清理操作。

因此,我尝试创建一个线程,该线程调用close()符合垃圾收集条件的测试对象的方法。run()尝试获取所有测试对象pre -mortem

实际上检索到的测试对象都是null. 预期的行为是检索测试对象并close调用方法。

无论您创建了多少测试对象,都没有一个测试对象可以事前捕获(您必须增加超时并多次调用 GC)。

我究竟做错了什么?这是一个Java错误吗?

可运行的测试代码:

我试图创建一个Minimal, Complete, and Verifiable example,但它仍然很长。我java version "1.8.0_121"在 Windows 7 64 位上使用 32 位。

预期输出:

实际输出:

0 投票
2 回答
822 浏览

java - 在 java.lang.ref.Reference 类中使用 clear

我看到 java 文档说该clear方法清除了这个引用对象。我不明白这是什么意思。这是否clear来自内存,换句话说,对象已被垃圾收集?

0 投票
1 回答
408 浏览

java - 删除具有通用 PhantomReference 类的本地对等点

正如 Hans Boehm 在 Google I/O '17 演讲“如何在 Android 中管理本机 C++ 内存”中建议我使用PhantomReference该类来确保正确删除本机对等点。

18 分 57 秒的链接视频中,他展示了一个对象的示例实现,该对象将自身注册到PhantomReference该类的类型中。这PhantomReference堂课,他在19 分 49 秒时显示。所以我为我的示例对象复制了他的方法。见下文。

虽然这种方法效果很好,但它不能扩展。我将需要创建相当多的对象,但我还没有找到一种方法来创建一个基类(对于我的对象或PhantomReference基类),它可以接受任何对象并正确处理本机删除。

如何创建一个PhantomReference可以在提供的对象上调用本机静态方法的通用基类?

我试图转换PhantomReference泛型,但本机静态删除方法阻碍了实现。

我的WorkViewModel

我的WorkViewModelPhantomReference

0 投票
0 回答
527 浏览

java - 如何在 Java 9 中卸载包含静态本机资源的 ClassLoader

我有一个提供Resource类的库,应该由 Java 9 清理Cleaner

假设我有一个CleanerMain使用Resource. 应用程序会创建两个Resource,一个供本地使用,另一个存储在静态字段中。

应用程序将被加载到一个ClassLoader(例如作为一个 OSGi 模块或一个 WAR 文件)中。我希望ClassLoader应用程序终止后将被卸载。

但是,ClassLoader从来没有卸载过。我从未见过日志Running Cleaner for global_resource,但Running Cleaner for local_resource会显示。

可以通过启动sbt shell 并执行来重现该问题runMain CleanerMain

注意我提供了一个 sbt 任务来执行System.gc()。但它并不能帮助 JVM 收集 global_resource 或卸载 ClassLoader。

如果我删除Resource SINGLETON.

然后 JVM 能够卸载ClassLoader.

我也试过了finalize。与, 不同Cleanerfinalize不会阻止类卸载。不幸的是,它在 Java 9 中已被弃用。

那么,确保在 Java 9 中清理静态本机资源的正确方法是什么?

  • 作为库作者,我应该创建 staticCleaner吗?
  • 作为应用程序开发人员,我应该创建静态资源吗?
  • 作为应用服务器开发人员,我应该如何卸载模块?
0 投票
2 回答
272 浏览

java - 为什么幻影引用没有排队?

我正在学习幻像引用,我很困惑当引用对象被垃圾收集时,幻像引用是如何排队的。

这是我的代码

正如预期的那样,queue.poll 将返回幻像引用:ref。

但是如果我对代码做一点改动:删除局部变量“ref”,queue.poll 将返回 null。

所以我可以推断,当 JVM 尝试对对象进行垃圾收集时,它会检查所有引用以查看是否有任何可以到达该对象的引用。

这应该是一个非常缓慢的进展。?

我设计了一个程序:使用幻像引用来跟踪资源泄漏。分配资源时,新建了一个幻像引用并绑定到资源。然后我发现:必须存储所有幻像引用,否则幻像引用不会入队。

我检查了netty代码,发现netty存储了所有幻像引用:io.netty.util.ResourceLeakDetector#allLeaks。

0 投票
1 回答
99 浏览

java - 有什么方法可以判断方法是否结束或方法中的本地不再使用?

在这种情况下,我需要一些解决方案来帮助我了解一些方法:

如果此方法已结束或 obj 是否无法访问(这将表明该方法已结束)。

我正在编写一个小型 Java 代理,我希望有一些技术可以让我确定此方法已结束或 obj 无法访问……在我的情况下,“do stuff”部分根本不使用 obj . 它不会将此变量传递到其他地方或将其添加到某个集合中。

我知道通过 Weak/Soft/Phantom-References 我可以部分实现这一点。如果调用 GC,则通过:

我总是可以在不同的地方验证:

然而,这只有在 GC 发生时才可能成立。

有没有其他方法可以实现这一目标?例如,一些标记 JVM 可能会放在这个变量上,因为很明显这是一个绝对可以垃圾回收的本地变量......

我不想依赖 ASM - 并为所有这些方法添加一个 try-finally 包装器。希望有一个更微妙的、基于参考的解决方案。

0 投票
1 回答
1243 浏览

java - Java PhantomReference 与 finalize()

我一直在阅读这篇关于 PhantomReference https://www.baeldung.com/java-phantom-reference的文章,并在那里找到了简化的示例代码:

这是输出:

所以一切都按预期工作,对对象的强引用设置为 null ,由 GC 检测到,幻像引用被添加到队列中。

现在在那篇文章中他们说:“垃圾收集器在执行其引用对象的 finalize 方法后向引用队列添加一个幻像引用。这意味着该实例仍在内存中。”

所以我想做一个测试并覆盖 finalize 方法,如:

但是输出不同,幻影引用不再添加到队列中:

有人可以解释为什么在此更改后输出不同以及如何更改此代码以便将幻像引用添加到队列中吗?

我一直在 JDK 8 和 11 上对此进行测试,两个平台上的结果相同。

0 投票
2 回答
454 浏览

java - java中的引用是什么?

referent在java语言中是什么意思?

我在用 java 阅读时遇到了这个词,phantom references但在那里没有解释,只是使用了(这个词)。我也无法通过谷歌搜索找到答案。

我可以从上下文中得出的结论是,它是引用指向的对象,但不确定,所以我想确定它是什么。

编辑:正如评论中所建议的,我正在添加一个正在使用该词的上下文:

垃圾收集器在执行其引用对象的 finalize 方法后,将幻像引用添加到引用队列。这意味着该实例仍在内存中。

0 投票
3 回答
192 浏览

java - 对“this”有一个 PhantomReference 是否安全?

我有一个共享资源,我想知道有多少其他对象仍在使用该资源。为此,我想使用PhantomReferences。

由于ReferenceQueues 不跟踪为它们注册的引用(source,“通知”部分),我的想法是将引用存储为被跟踪对象的字段:

这是否安全,基于PhantomReferences 的 Java 9(+) 行为,或者是否有可能在没有将引用添加到队列的情况下对实例进行垃圾收集?

文档说:

假设垃圾收集器在某个时间点确定对象是幻影可达的。那时,它将自动清除对该对象的所有幻像引用以及对该对象可从中访问的任何其他幻像可访问对象的所有幻像引用。在同一时间或稍后的某个时间,它会将那些在引用队列中注册的新清除的幻像引用排入队列。

但它没有提到垃圾收集是否可以在引用入队之前发生。