Java在序列化期间堆空间不足 [英] Java out of heap space during serialization
问题描述
以下代码导致OutOfMemmoryError:约300万行的堆空间。
分配给JVM的内存为4 GB,使用64位安装。
pre $
while(rs.next())
{
ArrayList< String> arrayList = new ArrayList< String>();
for(int i = 1; i< = columnCount; i ++)
{
arrayList.add(rs.getString(i));
}
objOS.writeObject(arrayList);
$ b ArrayList引用的内存有资格在每次迭代中进行垃圾回收while循环和内部JVM调用垃圾回收( System.gc()
),因为堆空间引发OutOfMemory错误。
那么为什么会发生异常?
解决方案 是 objOS
ObjectOutputStream
?
如果是这样,那么这是您的问题: ObjectOutputStream 保持对每一个对象的强烈引用,这是为了避免两次写同一个对象(它只会写一个引用,说我之前编写的那个对象id x )。
这意味着您正在有效泄漏所有 ArrayList
istances。
您可以通过调用 ObjectOutputStream $ c $> reset() < C>。由于您似乎并不是使用这个特性,所以您可以直接在 writeObject()之后调用 reset()
)
呼叫。
The following code is causing a OutOfMemmoryError: heap space for some 3 million rows.
Memory allocated to JVM is 4 GB, using 64 bit installation.
while (rs.next())
{
ArrayList<String> arrayList = new ArrayList<String>();
for (int i = 1; i <= columnCount; i++)
{
arrayList.add(rs.getString(i));
}
objOS.writeObject(arrayList);
}
The memory referenced by the ArrayList is eligible for garbage collection in each iteration of the while loop, and internally JVM calls garbage collection (System.gc()
) before throwing an OutOfMemory Error because of heap space.
So why is the exception occurring?
解决方案 Is objOS
an ObjectOutputStream
?
If so, then that's your problem: An ObjectOutputStream
keeps a strong reference to every object that was ever written to it in order to avoid writing the same object twice (it will simply write a reference saying "that object that I wrote before with id x").
This means that you're effectively leaking all ArrayList
istances.
You can reset that "cache" by calling reset()
on your ObjectOutputStream
. Since you don't seem to be using that feature anyway, you could call reset()
directly after the writeObject()
call.
这篇关于Java在序列化期间堆空间不足的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文