序列化期间Java的堆空间不足
问题内容:
以下代码导致OutOfMemmoryError:大约300万行的堆空间。使用64位安装,分配给JVM的内存为4 GB。
while (rs.next())
{
ArrayList<String> arrayList = new ArrayList<String>();
for (int i = 1; i <= columnCount; i++)
{
arrayList.add(rs.getString(i));
}
objOS.writeObject(arrayList);
}
ArrayList引用的内存在while循环的每次迭代中都可以进行垃圾回收,并且System.gc()
由于堆空间的原因,内部JVM
在抛出OutOfMemory错误之前会调用垃圾回收()。
那么为什么会发生异常呢?
问题答案:
是objOS
的ObjectOutputStream
?
如果是这样,那就是您的问题:An ObjectOutputStream
会对曾经写入过的 每个
对象保持强大的引用,以避免重复写入同一对象(它只会写一个引用说“我之前用id x 编写过的那个对象”) )。
这意味着您实际上在泄漏 所有 ArrayList
方面。
你可以通过调用重置“缓存”
reset()
在你的ObjectOutputStream
。由于writeObject
无论如何在两次调用之间似乎都没有利用该缓存,因此可以在调用reset()
之后直接writeObject()
调用。