0

我有运行在 HotSpot jvm 1.8.0_45 上的应用程序,具有良好的 8GB 堆。应用程序尝试为新对象分配内存失败并出现堆空间 OOM 错误。我查看了堆转储,发现大部分空间被 T4CConnection 实例的 charBufferCaches 占用。此缓存保存 char 数组的 SoftReference。我很惊讶 SoftReferences 没有在 OOM 之前发布。我仔细检查了这个数组是否有硬引用,但没有找到。

当应用程序通过 SoftReferences 保存 3GB 的字符数组时,为什么我有堆空间 OOM?为什么当应用程序需要新内存时这个 SoftReferences 没有被释放?

显示 charBufferCache 的 T4CConnection 对象的一部分:

显示 charBufferCache 的 T4CConnection 对象的一部分

T4CConnection charBufferCache 中保存的 char 数组的传入引用:

在 T4CConnection charBufferCache 中保存的 char 数组的传入引用

4

2 回答 2

1

理想情况下,应该在抛出 OOM 之前清除软引用。我怀疑程序中存在一些内存泄漏..

您可能想看看这里 -如何在 Java 中清除软引用?

尝试-XX:SoftRefLRUPolicyMSPerMB=<value>参数来限制软引用的大小并检查它是否有帮助。这可能为下一步提供方向。

于 2016-03-04T09:06:03.407 回答
-1

SoftReference 或 WeakReference 只有在对象被清理后才会被清除。它不会阻止对象被收集,但如果该对象在某处具有强引用,它将在 GC 后保留。

例如

Double d = new Double(123456);
WeakReference<Double> ref = new WeakReference<>(d);
System.gc();
System.out.println(ref.get() + " == " + d); // both not null.
于 2016-03-04T09:15:41.660 回答