2

Ich arbeite an Spring Batch und ThreadPoolTaskExecutor zum Fork mehrere Threads. Die Dateien sind riesig wie 175 MB und ich habe es mit vielen Strings-Objekten zu tun. Aufgrund dieser OutOfMemory Fehler wird geworfen.Im Frühling Batch ThreadPoolTaskExecutor Referenzen sind nicht Müll gesammelt

Unter Config ruft 1 Thread auf, um 1 Datei zu verarbeiten (customDBPartitioner nimmt die Dateien auf). Hier

ist die 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> 

Also, wenn dieser Schritt aufgerufen wird: 3 Threads startet Dateien verarbeiten, einen Scheck auf Speicher halten ich einen Zustand, in stepListener gesetzt worden.

while(preProcessorUtil.getAvailableMemory() < minimumMemoryRequired) { logger.info("Thread going to sleep as memory is not enough - " + inputFile.getFilename()); Thread.sleep(5000); }

Was ich versuche, ist, wenn genügend Speicher nicht verfügbar ist, dann gehen Sie nicht den Schritt zur Verarbeitung nächste Datei auszuführen.

Nachdem der verfügbare Arbeitsspeicher unter den memoryRequired fällt, wechselt der Thread in den Ruhemodus, aber GC wird nie aufgerufen und stattdessen nimmt der Speicher weiter ab.

Kann jemand bitte helfen und lassen Sie mich wissen, was ist das Problem hier, wie den Speicher zurückfordern, um die Dateien zu verarbeiten?

EDIT: In jvisualvm, die meisten Speicher von Strings/Zeichen genommen wird

Chunk Größe ist 1 Das heißt: Ich bin jeden Thread fragen einmal zu lesen/Arbeiten an einer Datei auf. Die Dateigröße variiert von KB bis 100 MB. Ich kann keine Option wählen, um Datei Zeile für Zeile zu verarbeiten, weil ich während der Verarbeitung
verschiedene Abschnitte in der Datei verweisen muss. Hier ist der Code aus dem Reader Es ist

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

Nach dem Lesen der ganze Datei in einem Stringbuilder eine Datei in einem Klumpen zu lesen, ich habe vielen Mustervergleich im Prozessor.

+0

Wie groß ist Ihre Chunk-Größe? Auch das Multithreading-Lesen einer Datei erzielt über die Leistung normalerweise keinen großen Vorteil. –

+0

Ihr Speicherverlust ist nicht in dem Code, den Sie gepostet haben. Sie sollten Ihren tatsächlichen E/A-Code oder Code, der Hash-Maps verwendet, veröffentlichen. Meine erste Vermutung ist, dass Sie die Streams, die Dateien in den Speicher lesen, nicht schließen. – ngreen

+0

Ich habe gerade meine Frage bearbeitet, um die obigen Fragen zu vertuschen. – Ramandeep

Antwort

1

Um das Problem zu lösen, müssen Sie möglicherweise am Ende die jmap-dunp-Dateien mit Eclipse MAT oder anderen Tools analysieren. Da das Problem mit jedem Detail Ihres Codes in Beziehung stehen kann.

Ich gebe nur einen möglichen Grund hier: ExecutorService hat eine BlockingQueue für wartende Aufträge verwendet, diese wartenden Jobs behalten auch Speicher. Wenn Sie den Job also zu schnell einreichen, ist es leicht, einen nicht ausreichenden Arbeitsspeicher zu erhalten.

+0

Es scheint nicht der Fall zu sein, ich habe auch die Schlafmethode ausprobiert, um die Ausführung zu verlangsamen. – Ramandeep

Verwandte Themen