gpt4 book ai didi

java - 为什么我的变量没有超出范围?

转载 作者:搜寻专家 更新时间:2023-10-31 19:34:44 25 4
gpt4 key购买 nike

大家下午好

有人告诉我,当函数返回时,变量(在该函数的范围内)会自动超出范围,因此我们不必将它们设置为 null。

然而,这似乎不是真的。

我有一个创建 java.lang.ref.PhantomReference 的测试代码指向 java.lang.Object 的实例.对该对象的唯一强引用在函数 F 的范围内。

换句话说,当该函数返回时,不应再有对该对象的任何强引用,并且该对象现在应该可由 GC 回收。

但是,无论我多么努力地尝试使 JVM 内存不足,GC 都只是拒绝收集该对象。令人惊讶的是,如果我将变量设置为 null (obj = null;),GC 现在会收集该对象。

这种奇怪现象背后的解释是什么?

public class Test {
public static void main(String args[]) {
// currently testing on a 64-bit HotSpot Server VM, but the other JVMs should probably have the same behavior for this use case
Test test = new Test();
test.F(new Object());
}

public <T> void F(T obj) {
java.lang.ref.ReferenceQueue<T> ref_queue = new java.lang.ref.ReferenceQueue<T>();
java.lang.ref.PhantomReference<T> ref = new java.lang.ref.PhantomReference<T>(obj, ref_queue); // if this line isn't an assignment, the GC wouldn't collect the object no matter how hard I force it to
obj = null; // if this line is removed, the GC wouldn't collect the object no matter how hard I force it to
StartPollingRef(ref_queue);
GoOom();
}

private <T> void StartPollingRef(final java.lang.ref.ReferenceQueue<T> ref_queue) {
new java.lang.Thread(new java.lang.Runnable() {
@Override
public void run() {
System.out.println("Removing..");
boolean removed = false;
while (!removed) {
try {
ref_queue.remove();
removed = true;
System.out.println("Removed.");
} catch (InterruptedException e) { // ignore
}
}
}
}).start();
}

private void GoOom() {
try {
int len = (int) java.lang.Math.min(java.lang.Integer.MAX_VALUE, Runtime.getRuntime().maxMemory());
Object[] arr = new Object[len];
} catch (Throwable e) {
// System.out.println(e);
}
}
}

最佳答案

符合标准的 JVM 永远不会有义务收集内存。也就是说,您不能编写一个程序,其正确性取决于在特定时间收集的特定内存位:您既不能强制 JVM 进行收集(即使通过 System.gc()! ) 也不依赖它这样做。

因此,从定义上讲,您所观察到的行为不可能是错误的:您是在有目的地让环境做一些它没有责任去做的事情。

总而言之,您的问题是您的对象没有超出范围。它在 main 中创建,然后以正常的 Java 引用方式传递给 F。在 F 返回之前,T obj 名称仍然是对您的对象的引用。

goOom 设为静态并在 main 中调用它,您应该会看到该对象已被收集。但是,话又说回来,您可能仍然没有,那也不是...

关于java - 为什么我的变量没有超出范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9440273/

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