2012-10-08 72 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的的獲取大小作爲信號讓驅動程序逐行地對結果集進行流式處理。在此之後,用該語句創建的任何結果集都將逐行檢索。