2

私はSpring Batchで作業しており、ThreadPoolTask​​Executorを使用して複数のスレッドをforkしています。 ファイルは175 MBのように巨大で、私はたくさんのStringsオブジェクトを扱っています。 このため、OutOfMemoryエラーがスローされています。Spring Batch ThreadPoolTask​​Executorリファレンスはガベージコレクトされていません

以下の設定は、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); 
    } 

を一つのファイルを読んで、私は、プロセッサにパターンマッチングの多くを行います。

+0

チャンクサイズはどのくらいですか?また、ファイルのマルチスレッド読み取りは、通常、パフォーマンスによって大きな利益を得ません。 –

+0

あなたのメモリリークは投稿したコードにありません。ハッシュマップを使用する実際のI/Oコードまたはコードを投稿する必要があります。私の最初の推測では、ファイルをメモリに読み込んでいるストリームを閉じていないということです。 – ngreen

+0

私は上記の質問を隠すために私の質問を編集しました。 – Ramandeep

答えて

1

問題を解決するには、Eclipse MATまたはその他のツールを使用してjmap dunpファイルを解析する必要があります。問題はコードの細部に関係しているためです。

ここでは、ExecutorServiceには待機中のジョブにBlockingQueueが使用されていますが、これらの待機中のジョブもメモリを保持しています。したがって、仕事をあまりにも速く提出すると、メモリが足りなくなります。

+0

それはケースではないようですが、私も実行を遅くするためにスリープメソッドを試してみました。 – Ramandeep

関連する問題