2017-09-14 3 views
0

verarbeite ich eine riesige CSV (1 GB) mit Java-Code.java.lang.OutOfMemoryError Während der Verarbeitung einer großen CSV-Datei

Meine Anwendung läuft auf 2-Core-Maschine mit 8 GB Speicher.

Ich benutze unten Befehl, um meine Anwendung zu starten.

Applcation startet einen Thread, um CSV von S3 zu laden und zu verarbeiten. Anwendung funktioniert für einige Zeit, aber OutOfMemoryError zur Hälfte Verarbeitung der Datei.

Ich bin auf der Suche nach einer Möglichkeit, die CSV-Datei weiter zu verarbeiten und gleichzeitig die Speicherauslastung gering zu halten.

im CSV-Prozess Ich bin der Durchführung folgender Schritte:

//Step 1: Download FROM S3 
String bucketName = env.getProperty(AWS_S3_BUCKET_NAME); 
AmazonS3 s3Client = new AmazonS3Client(credentialsProvider); 
S3Object s3object = s3Client.getObject(new GetObjectRequest(bucketName, key)); 
InputStream inputSteam = s3object.getObjectContent(); //This Stream contains about 1GB of data 

//Step 2: Parse CSV to Java 
ObjectReader oReader = CSV_MAPPER.readerFor(InboundProcessing.class).with(CSV_SCHEMA); 
try (FileOutputStream fos = new FileOutputStream(outputCSV, Boolean.FALSE)) { 
    SequenceWriter sequenceWriter = CsvUtils.getCsvObjectWriter(InboundProcessingDto.class).writeValues(fos); 
    MappingIterator<T> mi = oReader.readValues(inputStream) 

    while (mi.hasNextValue()) { 
     InboundProcessing inboundProcessing = mi.nextValue(); 
     inboundProcessingRepository.save(inboundProcessing); // this is Spring JPA Entity Save operation. (Almost 3M records so 3M calls)      
     sequenceWriter.write(inboundProcessingDto); // this is writing to a CSV file on local file system which is uploaded to S3 in next Step 
    } 
} catch (Exception e) { 
    throw new FBMException(e); 
} 
+2

Es sieht so aus, als ob Sie das ganze Ding sofort in den Speicher einlesen. Ist das notwendig? – pvg

+1

Wenn Ihr Startbefehl wirklich 'java -Xms4g -Xms6g ...' enthält, sollten Sie ihn in 'java -Xms4g -Xmx6g ...' korrigieren. – blafasel

+0

Danke. Es war ein Tippfehler. – Pramod

Antwort

0

Ich fand Grund für OOM. Obwohl ich die Datei richtig lese. Datei Zeile für Zeile lesen und alte Zeile verwerfen, sobald ich mit der Bearbeitung fertig bin. Das schafft kein Problem.

Problem ist, wenn ich das gleiche auf die Datenbank schreibe.

Mein Code wird in einem Transaktionsblock ausgeführt, aufgrund dessen Entitäten erst freigegeben werden, wenn die Transaktion abgeschlossen ist. Kurz gesagt, alle 3M-Einheiten werden im Speicher gehalten, bis die Transaktion festgeschrieben ist.

Ich konnte zu dieser Schlussfolgerung gelangen, sobald ich Finalize-Methode in meine verdächtigen Objekte hinzugefügt. Alles, was ich sehen konnte, ist, dass DTOS (temporäres Pojo) als sehr schnelle Geschwindigkeit verworfen wird, aber nicht einmal eine einzelne Entität verworfen wird. Schließlich wurden plötzlich alle Entitäten verworfen.

0

1) Split der Big-Size-Datei in kleiner Größe Dateien.

2) Verarbeiten Sie jede Datei einzeln nacheinander oder parallel.

prüfen Link zu Split-Datei in kleine Größe: https://stackoverflow.com/a/2356156/8607192

Oder

Verwenden Unix-Befehl "split für Split auf Größe basiert".

Verwandte Themen