2013-05-31 11 views
7

Sto valutando dati diversi da un file di testo in un algoritmo piuttosto grande.Limite di sovraccarico del GC Java superato - Soluzione personalizzata necessaria

Se il file di testo contiene più di datapoints (il minimo che mi serve è sth come 1,3 milioni di datapoint.) Dà il seguente errore:

Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded 
    at java.util.regex.Matcher.<init>(Unknown Source) 
    at java.util.regex.Pattern.matcher(Unknown Source) 
    at java.lang.String.replaceAll(Unknown Source) 
    at java.util.Scanner.processFloatToken(Unknown Source) 
    at java.util.Scanner.nextDouble(Unknown Source) 

quando sono in esecuzione in Eclipse con le seguenti impostazioni per il jre6 installato (di serie VM):

-Xms20m -Xmx1024m -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 -XX:NewSize=10m 
-XX:MaxNewSize=10m -XX:SurvivorRatio=6 -XX:TargetSurvivorRatio=80 
-XX:+CMSClassUnloadingEnabled 

Nota che funziona bene se corro solo attraverso una parte del file di testo.

Ora ho letto molto su questo argomento e sembra che da qualche parte devo avere una perdita di dati o sto memorizzando troppi dati in array (che credo di fare).

Ora il mio problema è: come posso aggirare questo?

  • È possibile modificare le impostazioni in modo tale da poter eseguire ancora il calcolo o ho davvero bisogno di più potenza di calcolo? (non ho idea di dove ottenerlo)
  • Ho letto da qualche parte che è meglio usare id e puntatori per la CPU piuttosto che inserire i dati negli array e lasciare che lo elabori. Ma come posso cambiare il mio codice in modo tale da fornire solo dei puntatori?

Fondamentalmente sto cercando alcune linee guida generali per prevenire un'enorme memoria/perdita di memoria.

+0

Come possiamo essere certi di sapere esattamente cosa significa? Tutto quello che abbiamo è che tu * pensi * così. –

+0

Ho letto questo: http://stackoverflow.com/questions/1393486/what-does-the-error-message-java-lang-outofmemoryerror-gc-overhead-limit-excee –

+2

Penso che dovrai richiedere i servizi di un profiler per questo. Consiglio vivamente Visualgc. –

risposta

3

Il vm arg veramente critico è -Xmx1024m, che indica alla VM di utilizzare fino a 1024 megabyte di memoria. La soluzione più semplice è usare un numero più grande lì. Puoi provare -Xmx2048m o -Xmx4096m, o qualsiasi numero, assumendo che tu abbia abbastanza RAM nel tuo computer per gestirlo.

Non sono sicuro che trarrete molti vantaggi da qualsiasi altro argomento di VM. Per la maggior parte, se dici a Java quanto spazio usare, sarà intelligente con il resto dei parametri. Suggerirei di rimuovere tutto tranne il parametro -Xmx e vedere come si comporta.

Una soluzione migliore è cercare di migliorare il proprio algoritmo, ma non l'ho ancora letto in modo sufficientemente dettagliato da offrire suggerimenti.

+0

Questo sembra avere un senso. Quindi ho circa 4 RAM. Ciò significa che dovrei essere in grado di aumentare -Xmx a circa 2048? Ci proverò domani e ti faccio sapere se ha funzionato. (È sera qui) –

+2

Corretto. Se sei fortunato, questo sarà sufficiente per il tuo set di dati e non dovrai più preoccuparti di cambiamenti più difficili e dispendiosi in termini di tempo. Con un totale di 4 GB, potresti probabilmente ottenere fino a 3 GB nel tuo VM, anche se potresti aver bisogno di chiudere alcuni altri programmi. –

+0

Se funziona, ti darò i punti per una soluzione brevissima ma efficiente –

1

vi consiglio di

  • uso di un profiler per ridurre al minimo l'utilizzo della memoria. Sospetto che tu possa ridurlo di un fattore pari o superiore a 10x utilizzando primitive, dati binari e raccolte più compatte.
  • aumenta la tua memoria nel tuo computer. L'ultima volta che ho provato a testare centinaia di segnali, avevo 256 GB di memoria principale e questo a volte era appena sufficiente. Più memoria riesci a ottenere, meglio è.
  • utilizza file mappati in memoria per aumentare l'efficienza della memoria.
  • Riduci le dimensioni del set di dati fino a quando la macchina e il programma possono supportare.
+0

cosa intendi con '256 GB di memoria principale'. –

+0

La macchina ha 256 GB di memoria e utilizza file mappati in memoria che stavo usando quasi tutto. –

+0

Wow! Deve essere stato un progetto molto grande allora. Nessun mio file più grande (un file .txt che funge da database) è di circa 70 mb quindi sto bene. Ho risolto il mio problema, essendo più semplice di quanto pensassi: ho semplicemente dovuto aumentare la memoria massima consentita da Eclipse (anche se l'ho già messa a 1024m). Sono interessato a questi 'file mappati in memoria', quindi ne leggerò per uso futuro. Grazie per il tuo tempo e la tua risposta! –

3

come si sta dicendo che la dimensione dei dati è davvero molto grande, se non va bene in una memoria del computer anche dopo aver utilizzato argomento -Xmx JVM, quindi si consiglia di passare a cluster di calcolo, utilizzando molti computer che lavorano su il tuo problema. Per questo dovrai utilizzare l'interfaccia Message Passing (MPI).

MPJ Express è una buona implementazione di MPI per Java, o in linguaggi come C/C++ ci sono alcune buone implementazioni per MPI esistenti come Open MPI e mpich2. Non sono sicuro se ti aiuterà in questa situazione, ma sicuramente ti aiuterà nei progetti futuri.

+0

Grazie! Ottima alternativa! –

Problemi correlati