2014-10-09 23 views
0

,所以我必須使用JDBC的Java代碼使用事先準備好的聲明,看起來有點像這樣將數據插入到PostgreSQL數據庫:如何測試,如果一個PreparedStatement將要耗盡內存

PreparedStatement statement = // prep statement 

for (int value: values) { 

    statement.setInt(1, value); 
    statement.addBatch(); 
} 

statement.executeBatch(); 

的問題是,我偶爾會碰到例外java.lang.OutOfMemoryError: Java heap space。我環顧四周,但我找不到任何東西;我如何測試語句即將耗盡內存,以便可以執行批處理。類似這樣的:

PreparedStatement statement = // prep statement 

for (int value: values) { 

    statement.setInt(1, value); 
    statement.addBatch(); 

    if (statement.currentSize() + sizeof(int) > statement.mazSize()) { 

     statement.executeBatch(); 
    } 
} 

statement.executeBatch(); 

感謝您的任何幫助。

+0

您是否關閉了您創建的所有資源 - 準備好的語句,結果集等? – 2014-10-09 15:53:49

+0

當我批處理語句時,我看看內存消耗並在'%x == 0'後面刷新它們。你可以監視空閒的堆空間,但我只是懶得這樣做。 – Hannes 2014-10-09 15:54:17

+0

使用較小的批量大小說500並迭代執行。 – 2014-10-09 15:55:51

回答

2

沒有可靠的方法提前發現實例化是否會失敗。

但是,更重要的是:您可能會錯誤地使用JDBC批處理工具,這會在插入多行時解決網絡往返開銷問題。大於100的批量大小顯示收益遞減,實際上可能導致放緩。

因此,將您的批處理策略更改爲使用固定批量大小的小數字,兩位數整數。

+0

在完全隔離的事務中寫入10m條目,我發現,基於使用的db配置,在flush之前少於1k條目放慢了整個過程。 – Hannes 2014-10-09 15:58:48

+0

@hannes網絡方面,數據庫有多遠?在任何合理的生產系統中,它都非常接近。往返時間越長,需要的批量就越大。 – 2014-10-09 16:01:33

+0

這只是一跳,但大量使用。這是我的第一個mariadb,所以我最終花時間調整了它。但是您的聲明適用於db2,oracle和sqlserver。 – Hannes 2014-10-09 16:06:14