gpt4 book ai didi

java - 如何在运行时查找一个对象是否正在引用另一个对象

转载 作者:行者123 更新时间:2023-11-30 06:43:05 25 4
gpt4 key购买 nike

是否可以在运行时检查一个对象是否直接或间接引用另一个对象?

(我知道我可以使用 VisualVm 或类似工具来分析 HeapDump,但我想在运行时将其自动化)

我正在使用 WeakHashMaps,做这样的事情:

public class MyClass {

// the Runnable will be eventually removed if the key is collected by the GC
private static final WeakHashMap<Object, Runnable> map = new WeakHashMap<>();

public static void main(String[] args) {
MyClass a = new MyClass(2);
MyClass b = new MyClass(20);

a = null;// no more Strong references to a
b = null;// no more Strong references to b

System.gc();

for (Runnable r : map.values()) {
r.run();
}
// will print (20), becouse using format() in the lambda cause a Strong
// reference to MyClass (b) and thus the WeakHashMap will never remove b
}

public MyClass(int i) {

if (i < 10) {
map.put(this, () -> {
System.out.println(i);
});
} else {
map.put(this, () -> {
// this is subtle, but calling format() create a strong reference
// between the Runnable and MyClass
System.out.println(format(i));
});
}
}

private String format(Integer i) {
return "(" + i + ")";
}

}

在代码中,MyClass 的两个实例将自己(作为键)和一个可运行对象(作为值)添加到 WeakHashMap。在第一个实例 (a) 中,Runnable 简单地调用 System.out.println() 并且当实例 a 不再被引用时 (a = null) 该条目将从 map 中删除。在第二个实例(b)中,Runnable 还调用了format() MyClass 的实例函数。这将创建对 b 的强引用,并将 Runnable 添加到映射中将导致锁定条件,其中值是对阻止垃圾收集器收集的键的间接强引用。

现在我知道要避免这些情况(例如,在 lambda 中使用 Wea​​kreference),但在实际场景中这很容易错过,并且会导致内存泄漏。

因此,在将对添加到映射之前,我想检查该值是否以某种方式引用了该键,如果是,则抛出异常。这将是一个“调试”任务,将在生产中被禁用,所以我不在乎它是缓慢还是被黑客攻击。

---更新---

我正在尝试处理 WeakListeners,并避免在未引用时立即收集它们。所以我将它们注册为 notifier.addWeakListener(holder, e -> { ... });这会将监听器添加到 WeakHashMap 中,以防止在 holder 上线之前收集监听器。但是在监听器中任何对 holder 的引用都会创建一个锁:(

有没有更好的办法?

最佳答案

Reflection API使您可以访问运行时对象的所有字段(及其运行时类型,可能还有 Class 对象)。理论上,您可以遍历实例字段(和类中的静态字段)、字段的字段等的树。

虽然这是可能的,但我怀疑它是否可行。你写道你不关心性能,但对于开发运行来说它甚至可能太慢了。这就引出了实现您自己的缓存的规则 1:不要这样做。

关于java - 如何在运行时查找一个对象是否正在引用另一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52445894/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com