2013-04-29 22 views
5

Ho un database in cui memorizzo le fatture. Devo eseguire operazioni complesse per ogni mese con una serie di algoritmi che utilizzano le informazioni di tutte le fatture. Il recupero e l'elaborazione dei dati necessari per queste operazioni richiede una grande quantità di memoria poiché potrebbero esserci molte fatture. Il problema diventa sempre più grave quando l'intervallo richiesto dall'utente per questi calcoli arriva a diversi anni. Il risultato è che sto ottenendo un'eccezione PermGen perché sembra che il garbage collector non stia facendo il suo lavoro tra un calcolo mensile.Esiste un modo per liberare memoria durante l'elaborazione di dati di grandi dimensioni?

Ho sempre usato System.GC per suggerire al GC di fare il suo lavoro non è una buona pratica. Quindi la mia domanda è, ci sono altri modi per liberare la memoria a parte questo? È possibile forzare la JVM a utilizzare lo scambio HD per memorizzare temporaneamente i calcoli parziali?

Inoltre, ho provato a utilizzare System.gc alla fine di ogni mese di calcolo e il risultato è stato un elevato utilizzo della CPU (a causa del cosiddetto "garbage collector") e un utilizzo di memoria ragionevolmente inferiore. Questo potrebbe fare il lavoro ma non penso che questa sarebbe una soluzione adeguata.

+0

Se ci mostra un frammento del codice, potremmo fornire una guida migliore. Forse le tue variabili sono nel campo di applicazione sbagliato e quindi essere vivo troppo tempo. –

+1

A seconda del tipo di operazioni eseguite sui dati, potrebbe essere più veloce utilizzare direttamente il database per eseguire tali operazioni invece di caricare i dati in java, creare oggetti e allocare memoria ... Anche se questo non risponde alla domanda, ma se le tue operazioni sono principalmente * spostando * i numeri intorno, * facendo alcuni calcoli *, * leggendo * e * scrivendo * di nuovo .. beh allora il tuo database può eseguire quelle operazioni più velocemente, poiché è "* più vicino alla sorgente *" – GameDroids

risposta

2

Non utilizzare mai System.gc(). Ci vuole sempre molto tempo per correre e spesso non fa nulla.

La cosa migliore da fare è riscrivere il codice per ridurre al minimo l'utilizzo della memoria il più possibile. Non hai spiegato esattamente come funziona il tuo codice, ma ecco due idee:

  • Prova a riutilizzare le strutture di dati generate per ogni mese. Quindi, diciamo che hai una lista di fatture, riutilizzare quella lista per il prossimo mese.
  • Se è necessario tutto, è consigliabile scrivere i file elaborati in file temporanei mentre si esegue l'elaborazione, quindi ricaricarli quando si è pronti.
1

Dovremmo ricordare che System.gc() non esegue realmente Garbage Collector. Semplicemente chiede di fare lo stesso. La JVM può o meno eseguire il Garbage Collector. Tutto quello che possiamo fare è rendere disponibili strutture inutili per la raccolta dei dati inutili. È possibile fare lo stesso:

  1. Assegnazione di Null come valore di qualsiasi struttura di dati dopo che è stato utilizzato. Quindi nessun thread attivo sarà in grado di accedervi (in breve abilitandolo per gc).
  2. riutilizzare le stesse strutture anziché crearne di nuove.
Problemi correlati