gpt4 book ai didi

Java SoftReference 保证失败

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:21:37 25 4
gpt4 key购买 nike

JDK 7 文档中有关于 SoftReference 的内容。 :

"All soft references to softly-reachable objects are guaranteed to have been cleared before the virtual machine throws an OutOfMemoryError."

但是,在我的测试程序中,我一直看到 OutOfMemoryError(下面的“陌生人行为”部分除外):

// RefObjectTest.java

import java.util.*;
import java.lang.ref.*;

public class RefObjectTest {

public static void main(String[] args) {

ArrayList<byte[]> leaks = new ArrayList<>();

byte[] obj = new byte[10 * 1024 * 1024];

SoftReference<byte[]> ref = new SoftReference<>(obj);

// WeakReference is supposed to be eagerly GC'ed, but I see no
// difference in terms of program behavior: still get OOME.
//
// WeakReference<byte[]> ref = new WeakReference<>(obj);

obj = null;

while(true) {
byte[] x = ref.get();
if(x == null) {
System.out.println("Referent stands garbage collected!!");
break;
} else {
System.out.println("Referent still alive.");
}

// Leak memory in small, 10k increments. If soft reference
// worked the way it's advertized, then just before the OOME, the
// 10MB referent should have been GC'ed to accomodate this small
// 10K new memory request. But it doesn't appear to work that way!

// try {
leaks.add(new byte[10 * 1024]);
// } catch(OutOfMemoryError e) {
// System.out.println(ref.get() == null ? "Referent cleared" :
// "Referent still alive");
// }

// VERY STRANGE: If I re-instate the above try-catch block, then no OOME is
// thrown, and the program keeps printing "Referent still alive" lines
// forever until I finally kill it with a Ctrl+C.

// Uncommenting gc() tends to delay the OOME in terms of time,
// but OOME eventually does happen, and after the same number of
// iterations of this loop.
//
// System.gc();
}
}
}

这是输出:

$ java -Xmx15m RefObjectTest
Referent still alive.
...
Referent still alive.
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at RefObjectTest.main(RefObjectTest.java:38)

陌生人行为

非常奇怪的是,如果我重新设置 try-catch block ,程序似乎永远运行良好,打印“Referent still alive”。直到我厌倦并杀死它。

$ java -version
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
$
$ uname -a
Linux ida 3.10.11-100.fc18.x86_64 #1 SMP Mon Sep 9 13:06:31 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

我在这一切中错过了什么?

最佳答案

一点也不奇怪,分配失败抛出异常。通过捕获异常,您表示程序可以继续,通过不捕获异常,您表示您无法处理它并且程序退出。

在你的 while 循环中你正在做:

        byte[] x = ref.get();

这是从您的软引用创建一个新的强引用。一旦您这样做,它就不再符合收集条件。在继续进行新分配之前,您没有清除强引用。

完成测试后执行x = null

关于Java SoftReference 保证失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20901300/

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