2012-10-08 34 views
0

我想从循环中读取mysql数据库中的序列化对象,并在java中对它执行一些操作。 我已经写了下面的函数,用于从ResultSet对象返回对象。java内存不足异常(jdbc)

public static MyObj deSerializeCacheTagInfo(ResultSet res 
    ) throws SQLException, IOException, ClassNotFoundException 
{ 
    byte[] buf = res.getBytes(3); 
    ObjectInputStream objectIn = null; 
    if (buf != null) 
     objectIn = new ObjectInputStream(new ByteArrayInputStream(buf)); 
    MyObj info = (MyObj)objectIn.readObject(); 
    return info; 
} 

当我运行这段代码时,它给了我一个内存不足的例外。 我搜索了一下,发现它可能是因为结果集很大,并且它保存在内存中,所以我试图每次读取大约50行。

但这似乎也没有帮助。

在使用visualvm进行分析时,它报告所有空间被byte[] objects占用。 但我不完全确定发生了什么问题。

+0

您可以使用['getBinaryStream'](http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#getBinaryStream(int))而不是['getBytes'] (http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#getBytes(int))? – MadProgrammer

+0

数据库中的数据块有多大? –

+1

在byte [] buf = res.getBytes(3);之后关闭ResultSet; – Munesh

回答

0

,请返回前添加objectIn.close();,它可以帮助

+0

我意识到自己错过了关闭流之后抱有很高的期望,但似乎没有帮助。任何其他想法? –

+0

这是必需的,但在我的情况下,原因是我没有提取所有行后重新使用它,导致内存泄漏,因为Munesh在上面的注释中指出了结果集没有关闭。 –

0

您可以通过使用256MB的堆空间或-mx512m为512MB等选项-mx256m增加堆空间。

通过在网上设置VM参数来搜索增加的堆空间。

这可能帮助

Increase heap size in Java

+0

有一个内存泄漏是显而易见的。我希望得到关于它在哪里的想法,Munesh在上面的评论中回答。 –

3

默认情况下,MySQL JDBC驱动程序获取完整的ResultSet到内存中。

您可以将其更改为一个流像这样的东西取:

Statement st = connIn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); 
st.setFetchSize(Integer.MIN_VALUE); 

的只向前的组合,只读结果集,并且Integer.MIN_VALUE的的获取大小作为信号让驱动程序逐行地对结果集进行流式处理。在此之后,用该语句创建的任何结果集都将逐行检索。