永続化のために Data Nucleus 1.1.4 / JDO 2.3 を使用する Java Web アプリがあります。
大量の JDO オブジェクトを一度に保持するバッチ インポート操作があります。インポートするデータが非常に大きいために、OutOfMemoryError がスローされる状況がいくつかありました。
意図したパターンは、入力ストリームをループし、行を解析し、JDO オブジェクトをインスタンス化し、makePersistent を呼び出し、JDO オブジェクトへのオブジェクト参照を解放して、入力データのサイズに関係なくメモリ フットプリントをフラットに保つことでした。
この操作中にヒープの分析を行ったところ、JDO オブジェクト インスタンスが積み重なって、commit
発生するまで大量のメモリを占有しているように見えます。それらへの参照を保持していませんが、Data NucleusPersistenceManager
およびTransaction
実装が参照しているように見えます。org.datanucleus.ObjectManagerImpl
「ダーティ」JDO オブジェクト インスタンス (実際にはオリジナルのコピー) のリストを保持するオブジェクト。これにはおそらく正当な理由がありますが、フレームワークが各 JDO オブジェクトのコピーを保持する必要があることに少し驚きました。それらはコミット後に手放されますが、すべての挿入がアトミックに行われるようにしたいので、トランザクション内でこの操作を実行する必要があります。現在の状態では、メモリ使用量はデータ入力サイズと直線的に相関しているため、これらの OutOfMemoryErrors が発生する可能性があります。単一の操作ではない場合は、同時操作で発生します。
このようなバッチ JDO 挿入操作のメモリ フットプリントをフラットに近づけるためのヒントやベスト プラクティスはありますか?