簡體   English   中英

如何測試PreparedStatement是否將耗盡內存

[英]How to test if a PreparedStatement is going to run out of memory

所以我有一些Java代碼,使用JDBC使用准備好的語句將數據插入PostgreSQL數據庫,該語句看起來像這樣:

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();

謝謝你的幫助。

沒有可靠的方法來提前查明實例化是否會失敗。

但是,更重要的是:您可能濫用了JDBC批處理功能,該功能可以解決插入許多行時網絡往返開銷的問題。 批量大小超過100的批次顯示退貨遞減,實際上可能會導致速度降低。

因此,更改批處理策略以使用較小的兩位數整數的固定批處理大小。

我遇到了與您的代碼相似的問題,因為它假定輸入數組/列表( values )的大小最大為三位數-這是在代碼級別上進行編碼的開發人員的假設。

一天,陣列/列表接近14k,此代碼導致了OOM,盡管有一件事,我注意到數據已成功提交到DB(其Db2 + Oracle Weblogic設置)中,幾秒鍾后,出現了幾個OOM,系統下去了。

要解決此問題,我只需將statement.executeBatch(); 以如下所示的預先確定的固定大小,假設固定批次大小為100,

int counter = 0;
for (int value: values) {
    statement.setInt(1, value);
    statement.addBatch();
    ++counter;
    if(counter >= 100 ){
     statement.executeBatch();
     counter =0;
   }
}
statement.executeBatch();

我不確定這是否也與驅動程序有關,但是我認為固定的批次數量會因設置的不同而有所不同(我有一個強大的多節點DB2集群,並且Web App也位於相同的數據中心),我已經測試了多種大小,並且1000的速度相當快,沒有出現任何問題,但是我減小了大小,因為此代碼是從在線UI應用程序中踢出的,因此同一代碼可能會有多個觸發器。

我猜這將取決於兩者-一個可以保存在內存中的Statement對象的數量以及DB處理一個提交的批處理所花費的時間,因為代碼將等待那么長時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM