序列化期间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错误之前会调用垃圾回收()。

那么为什么会发生异常呢?


问题答案:

objOSObjectOutputStream

如果是这样,那就是您的问题:An ObjectOutputStream会对曾经写入过的 每个
对象保持强大的引用,以避免重复写入同一对象(它只会写一个引用说“我之前用id x 编写过的那个对象”) )。

这意味着您实际上在泄漏 所有 ArrayList方面。

你可以通过调用重置“缓存”
reset()在你的ObjectOutputStream。由于writeObject无论如何在两次调用之间似乎都没有利用该缓存,因此可以在调用reset()之后直接writeObject()调用。