没有垃圾收集器有时间收集 SoftReference,总是 OutOfMemoryError
No garbage collector has time to collect SoftReference, always OutOfMemoryError
尝试了所有垃圾收集器,一百万种不同的设置组合。
但结果总是一样的——OutOfMemoryError。
谁能说出哪个垃圾收集器能够及时删除软引用引用的对象
下面的示例模拟器代码
package com;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;
class SoftReferenceCollector {
private static class Data {
public long[] l = new long[100];
}
private List<SoftReference<Data>> list = new ArrayList<>();
public void startFillCollection(int durationInSec) {
long i = 0;
long start = System.currentTimeMillis();
long end = start + durationInSec * 1000;
while (System.currentTimeMillis() < end) {
list.add(new SoftReference<>(new Data()));
++i;
if (i % 10000 == 0) {
sleep(1);
if (i % 1_000_000 == 0)
sleep(1000);
}
}
}
private void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException ignored) {
}
}
}
public class Main6 {
public static void main(String[] args) {
SoftReferenceCollector softReferenceCollector = new SoftReferenceCollector();
softReferenceCollector.startFillCollection(11240);
}
}
Referents
(SoftReference
引用的对象)在抛出 OOO 异常之前被 GC 清除。
但是没有被垃圾收集的是 SoftReference
对象本身。它们也是对象,它们消耗堆内存。它们都被列表保存在内存中。 GC只清除它们指向的对象,即referent
.
运行 你的 JVM -XX:+HeapDumpOnOutOfMemoryError
。此标志将在 OOO 之前转储堆,以便您稍后可以对其进行分析。您可以使用 Eclipse 内存分析器。
您也可以尝试 -XX:+PrintReferenceGC
标志,它会打印一些关于清理这些类型的引用在 gc 周期中花费的时间的信息。
尝试了所有垃圾收集器,一百万种不同的设置组合。 但结果总是一样的——OutOfMemoryError。
谁能说出哪个垃圾收集器能够及时删除软引用引用的对象
下面的示例模拟器代码
package com;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;
class SoftReferenceCollector {
private static class Data {
public long[] l = new long[100];
}
private List<SoftReference<Data>> list = new ArrayList<>();
public void startFillCollection(int durationInSec) {
long i = 0;
long start = System.currentTimeMillis();
long end = start + durationInSec * 1000;
while (System.currentTimeMillis() < end) {
list.add(new SoftReference<>(new Data()));
++i;
if (i % 10000 == 0) {
sleep(1);
if (i % 1_000_000 == 0)
sleep(1000);
}
}
}
private void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException ignored) {
}
}
}
public class Main6 {
public static void main(String[] args) {
SoftReferenceCollector softReferenceCollector = new SoftReferenceCollector();
softReferenceCollector.startFillCollection(11240);
}
}
Referents
(SoftReference
引用的对象)在抛出 OOO 异常之前被 GC 清除。
但是没有被垃圾收集的是 SoftReference
对象本身。它们也是对象,它们消耗堆内存。它们都被列表保存在内存中。 GC只清除它们指向的对象,即referent
.
运行 你的 JVM -XX:+HeapDumpOnOutOfMemoryError
。此标志将在 OOO 之前转储堆,以便您稍后可以对其进行分析。您可以使用 Eclipse 内存分析器。
您也可以尝试 -XX:+PrintReferenceGC
标志,它会打印一些关于清理这些类型的引用在 gc 周期中花费的时间的信息。