Newsgroup: it.comp.java
Titolo: OutOfMemory: java heap

Salve a tutti, vi espongo brevemente la mia domanda.
Ho un'aplicazione che processa in modo iterativo una serie di
directoryì, per la precisione il loro contenuto. Il problema è che il
contenuto può facilmente aggirarsi sui 2000 files o più...in qualche
modo, dopo un po' mi viene lanciata una OutOfMemory. Il problema a
questo punto è...come procedere? Ia mia applicazione funziona così:
ho una LinkedList di stringhe contenenti il full path del file, itero
sulla lista e per ogni iterazione creo un nuovo oggetto File (ne ho
bisogno per quello che devo fare) e di questo File calcolo l'hash, piu
altre cose, quindi se non ci sono errori durante la fase di process del
File, elimino la stringa dalla lista, passsando quindi al prossimo
elemento, ecc.
Per "gestire" la OutOfMemory mi comporto così, semplicemente non
elimino dalla lista la String relativa al file "incriminato", in questo
modo ho "uno storico" dei file saltati per questa eccezione, senza
dover interrompere la procedura di parsing delle Direcory. Alla fine di
tutto il lavoro invoco un'altro metodo (chiamiamolo B) che si occupa di
rielaborare tutti le Stringhe che sono ancora nella lista. A questo
punto però tutti questi oggetti lanciano una OutOfMemory, che questa
volta viene semplicemente ignorata...
Non mi spiego questa cosa..perchè tutti le stinghe  che mi hanno
causato una OutOfMemory me la rilanciano dopo? Notare che in realtà
l'eccezione non viene lanciata dalla stringa ma al momento della
creazione dell'oggetto File. Ma una volta che io sono uscito dal metodo
A (quello che mi processa tutta la linkedList) gli oggetti File non
dovrebbero essere "rilasciati" dal GC??
Come posso fare per evitare questo comportamento? Ho gia provato ad
aumentare la memoria con -Xms ma otytengo solo l'effetto di spostare la
"soglia" in cui mi compare la OutOfMemory. (es anziche comparire
regolarmente ogni circa 100 file mi appare ogni circa 150,per dire
numeri a caso ma che rendono l'idea). Alternativamente, se il mi modo
di procedere non è quello giusto, come potrei fare?
Saluti


Questo è il punto fondamentale: innazitutto, i reference agli oggetti
File sono interni o esterni al metodo.
Perchè, se sono variabili di classe, il fatto che tu non ci faccia
nulla non importa. Deve essere l'oggetto istanza della tua classe che
non deve essere più utilizzato affinchè sia eleggibile per la gc.
Secondo: il metodo che fa la new dei File è chiamato N volte o ha al
suo interno un ciclo di iterazione? Perchè, nel secondo caso, gli
oggetti File sono comunque tutti in vita finchè il ciclo non termina.
Puoi provare a "forzare" la gc di quelli inutili con il finalize() ma
non hai nessuna certezza al riguardo.

 non hai nessuna certezza al riguardo.
Il metodo ha al suo interno un ciclo
while(iterator.hasNext()) {
String NomeFile = (String) iterator.next();
File fileObj = new File(NomeFile);
//altre cose
}
L'iteratore è invece definito per una LinkedList globale alla classe.

Scusa ma non ho capito una cosa: l'oggetto File creato nel loop poi lo
passi a qualcos'altro? Perchè se così non fosse, allora hai sempre un
solo oggetto attivo a giro (visto che il reference è sempre lo
stesso).
Tutt'al più puoi provare così:
File fileObj;
 while(iterator.hasNext()) {
String NomeFile = (String) iterator.next();
fileObj = null;
System.gc();


E` esattamente quello che faccio...a parte la System.gc()
L'oggetto file non lo passo da nessuna parte, viene utilizzato
solamente all'interno del loop
il loop completo e`:
 public function Elabora(){
File fileObj;
 while(iterator.hasNext()) {
String NomeFile = (String) iterator.next();
fileObj = new File(NomeFile);
byte[] hash = calcolahash(fileObj);
//altre cose
fileObj = null;
} // end while
System.gc();
} // end elabora
Il reference e` unico, come dici giustamente tu, ma gli oggetti sono
comunque istanziati e residenti in memoria.