Evitare un “errore di memoria insufficiente” in Java(eclipse), quando si utilizzano grandi struttura di dati?

StackOverflow https://stackoverflow.com/questions/2459972

Domanda

OK, sto scrivendo un programma che, purtroppo, ha la necessità di utilizzare una grande struttura di dati per completare la sua opera, ma si è verificato un "errore di memoria insufficiente" durante l'inizializzazione.Mentre ho capito del tutto cosa significa e perché è un problema, sto avendo difficoltà a vincere, dato che il mio programma deve utilizzare questa struttura di grandi dimensioni e non conosco nessun altro modo per memorizzare.

Il primo programma indici di un ampio corpus di file di testo che ho a disposizione.Questo funziona bene.

Allora usa questo indice per inizializzare una grande matrice 2D.Questo array ha n2 voci, dove "n" è il numero di parole nel corpus del testo.Per il relativamente piccolo pezzo sto testando o n e(circa 60 file) di circa 30,000x30,000 voci.Questo sarà probabilmente il più grande una volta che ho eseguito sul mio full inteso corpus troppo.

In modo coerente non riesce, ogni volta, dopo che gli indici, mentre si è inizializza la struttura dati(per essere lavorato in un secondo momento).

Le cose che ho fatto sono:

  • rinnovare il mio codice per l'utilizzo di un primitivo int[] invece di un TreeMap
  • eliminare strutture ridondanti, ecc...
  • Inoltre, ho eseguito il programma con-Xmx2g al massimo fuori la mia memoria allocata

Io sono abbastanza sicuro che questo non sarà una semplice riga di codice soluzione, ma è più probabile che sarà necessario un nuovo approccio.Sto cercando di capire che cosa questo approccio è, qualche idea?

Grazie, B.

È stato utile?

Soluzione

Suona come (fare alcune ipotesi su quello che si sta utilizzando la matrice per la maggior parte delle voci sarà 0.Se è così, si potrebbe considerare l'utilizzo di un matrici sparse la rappresentazione.

Se davvero sono che molte voci (corrente array è da qualche parte più di 3 gigabyte già, anche supponendo che non in testa), allora dovrai usare un qualche tipo di archiviazione su disco, o un pigro-carico/scarico del sistema.

Altri suggerimenti

Ci sono diverse cause dei problemi di memoria insufficiente.

In primo luogo, il caso più semplice è semplicemente bisogno di più di heap.Si utilizza 512M max heap quando il programma potrebbe funzionare correttamente con il 2G.Aumento con -Xmx2048m come opzione JVM e si sta bene.Anche essere consapevoli del fatto che a 64 bit Vm può utilizzare fino a due volte la memoria di 32 bit Vm a seconda del trucco dei dati.

Se il tuo problema non è semplice poi si può guardare ottimizzazione.La sostituzione di oggetti primitivi e così via.Questo potrebbe essere un'opzione.Davvero non posso dire in base a ciò che hai postato.

Alla fine, tuttavia, si arriva ad un incrocio in cui si deve fare una scelta tra virtulization e partizionamento.

La virtualizzazione in questo contesto, significa semplicemente una qualche forma di fingere che non ci sia più memoria di quella che c'è.Sistemi operativi utilizzano questo con spazio di indirizzi virtuali e l'utilizzo di spazio su disco rigido come memoria aggiuntiva.Questo potrebbe significare mantenendo solo alcune delle struttura di dati in memoria alla volta e persistente il resto di storage secondario (ad esempio, file o database).

Partizionamento è dividere i dati su più server (reale o virtuale).Per esempio, se si dovesse tenere traccia di stock quotata sul NASDAQ si potrebbe mettere stock codici che iniziano con "A" server1 "B" sul server2, etc.Hai bisogno di trovare un approccio ragionevole per suddividere i dati in modo tale che ridurre o eliminare la necessità per il cross-comunicazione perché la croce-la comunicazione è ciò che limita la scalabilità.

In modo semplice caso, se quello che stai memorizzazione 30K parole e 30K x 30K combinazioni di parole che si può suddividere in quattro server:

  • A-M x-M
  • A-M x N-Z
  • N-Z x-M
  • N-Z x N-Z

Questa è solo una idea.Di nuovo è difficile toc omment senza conoscere i dettagli.

Questo è un problema comune con dataset di grandi dimensioni.Puoi ottimizzare quanto vuoi, ma la memoria non sarà mai abbastanza (probabilmente), e non appena il set di dati cresce un po ' di più si sono ancora fumato.Il più scalabile soluzione è semplicemente quella di tenere meno in memoria, il lavoro sui blocchi, e mantenere la struttura del disco (database/file).

Se non avete bisogno di un intero a 32 bit (la dimensione di un numero intero) per ogni valore nella vostra matrice 2D, forse un tipo più piccolo come un byte sarebbe fare il trucco?Inoltre, si dovrebbe dare più spazio heap possibile - 2GB è ancora relativamente piccolo per un sistema moderno.La RAM è a buon mercato, soprattutto se sei in attesa di essere facendo un sacco di elaborazione in-memory.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top