Newsgroup: it.comp.java
Titolo: riprendersi da un OutOfMemoryError

Ciao a tutti, vi pongo un quesito tosto sul temibilissimo 
java.lang.OutOfMemoryError
Ho intenzione di catturare questo errore (basta un try/catch) e se è 
possibile, recuperare in qualche maniera la preziosa memoria senza che 
l'applicazione venga "suicidata" dalla VM; oppure, se proprio la 
situazione è tragica vorrei (in ordine di importanza):
1) salvare il lavoro dell'utente
2) informarlo che l'applicazione ha dei problemi con la memoria
3) uscire senza rompere tutto
Ho pensato a diverse strategie, ma non ho tempo e esperienza per 
stabilire se vanno bene, eccone alcune:
- installare un hook che cattura la terminazione della VM
- mantenere da qualche parte una struttura dati abbastanza grande da 
"nullare" al momento OutOfMemoryError; in questo modo si potrebbe 
recuperare un po' di memoria (sperando che il garbage collector sia 
ancora vivo e sano di mente)
- usare JNI
- altro
Un requisito fondamentale è: affidabilità. Quindi niente menate sulla 
portabilità al 100%, sull'eleganza o bandiere di vario genere.
La sfida è aperta...
-- 
                 ''~``
                ( o o )
+---------.oooO--(_)--Oooo.----+
 
http://megadix.clarence.com/
 
http://www.mict.it/

 Un requisito fondamentale è: affidabilità. 
Appunto :)
Ciao :)
pole

Dimitri De Franciscis wrote:

Siccome OutOfMemoryError puo' capitare letteralmente ovunque nel tuo 
codice (o nelle API che tu utilizzi) e' inattuabile scrivere ovunque dei 
try/catch.
La soluzione corretta, come suggerisci tu stesso, e' quella di:
  1) salvare il lavoro dell'utente
  2) informarlo che l'applicazione ha dei problemi con la memoria
  3) uscire senza rompere tutto
Per far cio' riscrivi i metodi run di ogni tuo thread (o dell'unico
main che eventualmente hai) nel seguente modo:
public void run() {
   try {
    // vecchio originario metodo run
   } catch(OutOfMemoryError) {
     // codice per 1) salvare il lavoro dell'utente
     // codice per 2) informarlo che l'applicazione ha dei
     //               problemi con la memoria
     System.exit(0); // cioe': 3) uscire senza rompere tutto
   }
}

quello che si scrive.
ah si.. allora spiegami questa:
ho un programma che alloca la memoria dinamicamente e non so quanta me
ne servirà, non posso assolutamente ottimizzarlo riguardo il consumo
di memoria perché lo ho già ottimizzato.
In che modo posso stare attento?
Ciao
Chairam

 try/catch.
E' inattuabile solo perchè un Error è un Error! Una Exception è un'exception!
Un programma java è un programma java! Una palla è una palla! ... and so on ...
Leggete la spiegazione di "pole" nel thread corrente (solo la prima parte).
Se proprio volete leggervi anche la seconda, allora leggetevi anche la replica-chiarimento
di "chiarimm!".
Umilmente GianpieroP.

 java.lang.OutOfMemoryError
Non sono espertone, ma non si potrebbe implementare un meccanismo che nel
caso in cui la memoria disponibile raggiunge un limite definito con il
meccanismo che più si ritiene adeguato (limite fisso, percentuale,
algoritmo di un qualche tipo), ferma tutto e dice all'utente:
"Attenzione, la memoria sta per finire, potresti perdere tutti i dati non
salvati. Vuoi salvare ora?"
Si può fare?
Raffaele

 di memoria perché lo ho già ottimizzato.
 > In che modo posso stare attento?
Dipende molto dal tipo di applicazione che scrivi. In moltissimi casi 
non sarebbe male appoggiarsi a meccanismi in grado di "swappare" sulla 
memoria di massa (l'esempio più comune è il database). Altrimenti, se i 
dati in memoria non sono critici, si potrebbero utilizzare dei weak 
reference in luogo degli strong reference comunemente utilizzati: in 
questo modo ilgarbage collector sarebbe sempre in grado di intervenire.
Chi ha progettato il linguaggio non ha spaccato a caso la gerarchia dei 
throwable in Exception ed Error: i secondi, come scritto nel pezzo di 
documentazione che ho riportato, sono utilizzati per indicare problemi 
davvero seri, e "a reasonable application should not try to catch".
A meno che non si reputi ragionevole che ad un certo punto del proprio 
lavoro l'utente sia piantato in asso dall'applicazione che gli dice 
"guarda, non niea faccio 'cchiù, chiudimi e riavviami! :-)".
Ognuno è libero di pensare come vuole, ma io un'applicazione così non la 
reputerei affidabile, come riterrei poco affidabile il programmatore che 
mi presentasse un listato pieno di "puntellature" a riparo di temuti 
errori fatali.
 > Ciao
 > Chairam
Ciao :)
pole



Rivedere le specifiche dell'applicazione pare brutto? Supponendo anche che
un'applicazione-server scritta in java giri su una macchina carrozzata
(leggi: 4Gb RAM se non di più, oppure file di paginazione particolarmente
esteso) e lasciando libertà di espansione alla JVM... quando mai si è vista
la necessità di tenere un intero database in memoria per un accesso
immediato? Non per niente una delle caratteristiche delle applicazini J2EE è
la passivazione degli EJB: quando nel breve termine non servono più, vengono
salvati su database e i riferimenti da essi occupati vengono posti a null,
lasciando libertà di intervento al garbage collector... e tutto questo è
fatto dal framework, il programmatore J2EE non deve preoccuparsi di nulla in
questo senso.
Allo stesso modo potresti ottimizzare ulteriormente la tua applicazione
scovando oggetti il cui uso non è immediato, o che sai per certo che non
verranno mai utilizzati contemporaneamente tutti assieme, e serializzarli su
file quando non servono subito (la classe java.io.File ha delle API apposite
per la creazione di file temporanei che verranno cancellati al termine della
JVM). Nel momento in cui hai bisogno di riutilizzare questi oggetti,
semplicemente li deserializzi e li usi.... e il ciclo continua così. Ok, mi
dirai che è complicato e non rende il massimo delle prestazioni, ma con
applicazioni che lavorano con grosse moli di dati penso sia l'unico modo.
-- 
Fermiamo Scientology prima che sia troppo tardi!!!
http://xenu.com-it.net
 - 
http://xenu.freewinds.cx/
(per rispondere personalmente leva IlDitoDalCulo)

 In che modo posso stare attento?
Aggiungo a quello che è stato detto che chi alloca tanta memoria potrebbe
controllarne prima la disponibilità.
Ciao
Matteo
-- 
chi sono e soprattutto chi non sono:
http://www.ilnomedeldominio.it
un piccolo programma per studenti universitari:
http://inutility.ilnomedeldominio.it

controllarne prima la disponibilità.
in effetti qui sta il problema
bisogna sapere 2 cose:
1- la quantità di memoria disponibile
2- la quantità di memeoria da allocare
1 penso si possa risolvere con Runtime.freeMemory()
2 non lo so
Ciao
Rob

errori fatali.
Magari sono io puntiglioso, in effetti l'outOfMem non è che capiti
tanto facilmente, però le eccezioni 'checked' ovvero obbligatorie, non
mi dire che non ti puzzano di puntellature.
Ciao
Chairam

applicazioni che lavorano con grosse moli di dati penso sia l'unico modo.
in effetti è una possibilità ma c'è un però:
ho un linguaggio che mi da un garbage collector per non  farmi
preoccupare della memoria e lasciarmi il tempo di pensare 'ad alto
livello' e poi sono obbligato a ragionare di operazioni tipo-swap e
tipo-sistema operativo? Questo è ridicolo.
imho necessitasi altra soluzione
E' vero che il problema non capita tanto spesso.
E' sorprendente come le cose cambino semplicemente modificando -Xmx.
A quanto ho potuto vedere la jvm fa una gestione un po' particolare
della memoria, privilegiando -giustamente- le prestazioni vedasi il
precedente thread '4 milioni di oggetti' e allocando la memoria con
'criteri suoi' più che in base alle necessità del programma.
Tuttavia avrei preferito qualcosa di meno definitivo di un Error e non
invasivo come una checked exception, qualcosa tipo 'posso allocare
questo oggetto?' da utilizzare a discrezione del programmatore conscio
del problema.
Ciao
Chairam

 mi dire che non ti puzzano di puntellature.
Per quale motivo? Le checked exceptions mettono in guardia il 
programmatore da eventi che possono normalmente accadere ed è quindi 
bene prevenirsi. Ad esempio se tento di aprire un file c'è sempre dietro 
l'angolo la possibilità che il file non ci sia.
Non è invece normale che l'applicazione vada via via "gonfiandosi" in 
memoria fino ad esplodere :-)
Ciao :-)
pole

 quel valore di ritorno e scelgo che provvedimenti prendere.
OT, ma giusto per puntualizzare:
"In C++ Standard, operator new deve sollevare una eccezione se
fallisce."
Vedi:
http://groups.google.com/groups?q=new+fallisce+group:it.comp.lang.c%2B%2B&hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=81lkdm%247hh%241%40serv1.iunet.it&rnum=2
ciaociao
-- 
Gerolamo
www.overweb.it

scopo dei weak reference.
interessante ci ho dato un'occhiata, non ho ancora capito se siano un
approccio che risolve il problema come lo intendo io ma sono un
escamotage interessante.
Ciao
Chairam