私はSpring Batchで作業しており、ThreadPoolTaskExecutorを使用して複数のスレッドをforkしています。 ファイルは175 MBのように巨大で、私はたくさんのStringsオブジェクトを扱っています。 このため、OutOfMemoryエラーがスローされています。Spring Batch ThreadPoolTaskExecutorリファレンスはガベージコレクトされていません
以下の設定は、1つのスレッドを呼び出して1つのファイルを処理します(customDBPartitionerがファイルを取得しています)。ここで
はconfigです:
<bean id="threadPoolTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="3" />
<property name="maxPoolSize" value="3" />
</bean>
<step id="unixPartitionerStep">
<partition step="unixItemStep" partitioner="customDBPartitioner">
<handler grid-size="10" task-executor="threadPoolTaskExecutor" />
</partition>
</step>
<listeners>
<listener ref="unixJobListener" />
</listeners>
このステップが呼び出されたときに:3つのスレッドは私がstepListenerに条件を入れているメモリのチェックを保つために、ファイルの処理を開始します。私がしようとしています何
while(preProcessorUtil.getAvailableMemory() < minimumMemoryRequired) { logger.info("Thread going to sleep as memory is not enough - " + inputFile.getFilename()); Thread.sleep(5000); }
は十分なメモリが利用できない場合は、次のファイルを処理するためのステップを実行するために行くいけないです。
使用可能メモリがmemoryRequired以下になると、スレッドはスリープモードになりますが、GCは呼び出されず、代わりにメモリが減少し続けます。
誰かが助けてくれて、ここで何が問題であるか、ファイルを処理するためにメモリを再利用する方法を教えてもらえますか?
EDIT:JvisualVMで 、ほとんどのメモリが文字列/文字によって取られ
チャンクサイズはつまり1 です:私は、一度に1つのファイルに/仕事を読み取るために、各スレッドを求めています。ファイルサイズは、KB単位から100 MB単位までです。 処理中に
がファイル内の別のセクションを参照する必要があるため、ファイルを1行ずつ処理するオプションを選択できません。ここで リーダーからのコードで、それはStringBuilderの中にファイル全体を読んだ後1つのチャンクに
StringBuilder file = new StringBuilder()
try {
// I tried this as well.
//file.append(FileUtils.readFileToString(resource.getFile()));
logger.info("Size of file : "+ resource.getFilename() +" is " + FileUtils.sizeOf(resource.getFile())/1024 + " KB");
synchronized(UnixFileItemReader.class) {
lineIterator = FileUtils.lineIterator(resource.getFile());
/*while(PreProcessorUtil.getAvailableMemoryNoLogs() < minimumMemoryRequired) {
Thread.sleep(5000);
}*/
while (lineIterator.hasNext()) {
file.append(lineIterator.nextLine()).append("\r\n");
}
}
} catch(Exception ex) {
ex.printStackTrace();
file = null;
throw ex;
} finally {
LineIterator.closeQuietly(lineIterator);
}
を一つのファイルを読んで、私は、プロセッサにパターンマッチングの多くを行います。
チャンクサイズはどのくらいですか?また、ファイルのマルチスレッド読み取りは、通常、パフォーマンスによって大きな利益を得ません。 –
あなたのメモリリークは投稿したコードにありません。ハッシュマップを使用する実際のI/Oコードまたはコードを投稿する必要があります。私の最初の推測では、ファイルをメモリに読み込んでいるストリームを閉じていないということです。 – ngreen
私は上記の質問を隠すために私の質問を編集しました。 – Ramandeep