4

Tomcat の HSQLDB に 1.000.000 エントリをできるだけ早く挿入する必要がありますが、このコードには 64m (Tomcat のデフォルト MaxPermSize) では不十分で、"OutOfMemoryError" が発生します (デフォルト設定で挿入したい)。

connection.setAutoCommit(false);
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO USER (firstName, secondName) VALUES(?,?)");
for (int i = 0; i < 1000000; i++) {
    preparedStatement.setString(1, "firstName");
    preparedStatement.setString(2, "secondName");
    preparedStatement.addBatch();
}
preparedStatement.executeBatch();
connection.commit();

私はこれを読んでいます:http://hsqldb.org/doc/2.0/guide/deployment-chapt.html#dec_bulk_operations。「SET FILES LOG FALSE」を設定しましたが、役に立ちません。

  1. MaxPermSize=64m で 1.000.000 エントリを挿入する方法はありますか?
  2. このコードで tomcat が大量のメモリを消費するのはなぜですか? 1.000.000 * 19 ("firstName" + "secondName" の長さ) * 2 (1 シンボルのバイト数) = ~40Mb です。
  3. キャッシュされたテーブルよりもメモリテーブルの挿入の方が高速なのはなぜですか? 私は何か間違っていますか?
4

1 に答える 1

5
  1. たぶん、より小さなセットでそれをやってみてください。消費するメモリが少なくなり、おそらくより効率的になります。
  2. メモリのサイズを計算するのははるかに困難です。たとえば、firstName を 100 万回保存する必要はありません。値は内部化されますが、参照を 100 万回保存する必要があります。次に、すべてのライブラリがメモリなどを消費します...
  3. 「キャッシュされたテーブル」とは何ですか?

それを試してみてください。少なくともメモリの消費量は少なくなります:

connection.setAutoCommit(false);
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO USER (firstName, secondName) VALUES(?,?)");
for (int i = 0; i < 1000000; i++) {
    preparedStatement.setString(1, "firstName");
    preparedStatement.setString(2, "secondName");
    preparedStatement.addBatch();
    if(i % 1000 == 0)
         preparedStatement.executeBatch();
}
preparedStatement.executeBatch();
connection.commit();

編集:パーマのサイズが原因ですか?スタックトレースを入れてもらえますか?

于 2012-11-22T07:54:19.817 に答える