Newsgroup: it.comp.java
Titolo: liberare la memoria dagli oggetti inutili

Dunque ho letto che"Java esegue la garbage collection automaticamente.
Quando l'ultimo riferimento ad un oggetto viene perduto l'oggetto
diventa candidato alla garbage collection.Di tanto in tanto la
macchina virtuale esegue un metodo che raccoglie tutti gli oggetti
candidati alla garbage collection e libera la memoria da essi
occupata, permettendo alla macchina virtuale di riutilizzarla"
Dunque se io ho una pagina jsp che si limita a stamparmi il valore di
2 stringhe:
<%
String a =new String("a");
String a1 =new String("a1");
out.println(a +a1);
%>
una volta che tale pagina è stata vista dall'utente e che questo
magari passa ad un'altra pagina la memoria occupata dai 2 riferimenti
(a e a1) a oggetti di tipo stringa non viene liberata.
non sarebbe allora + corretto scrivere qcosa del genere
<%
String a =new String("a");
String a1 =new String("a1");
out.println(a +a1);
a=null;
a1=null;
%>
in modo da liberare la memoria???
è una cosa troppo puntigliosa o è una buona norma di programmazione???
grazie,ciao

 è una cosa troppo puntigliosa o è una buona norma di programmazione???
Il risultato non cambia. Metti il caso che il garbage collector inizi a
lavorare subito dopo che l'interprete abbia inviato l'ultimo byte della
pagina, troverebbe i due oggetti referenziati da "a" e "a1" già non più
raggiungibili.
Per assurdo, è consigliabile non inserire istruzioni esplicite di
eliminazione di riferimenti, per il semplice motivo che è una perdita di
tempo: consuma una decina di cicli di processore che potrebbero essere
impiegati in qualcosa di più utile...
E poi, come disse Car Hoare (inventore dell'algoritmo di ordinamento
QuickSort) "l'ottimizzazione prematura è la radice di tutti i mali".
(grazie Dario per l'"imboccata" :P)
-- 
Fermiamo Scientology prima che sia troppo tardi!!!
http://xenu.com-it.net
  ---  
http://xenu.freewinds.cx
(per rispondere personalmente leva IlDitoDalCulo)

 (a e a1) a oggetti di tipo stringa non viene liberata.
Dopo che la pagina e' stata "visitata", lei stessa viene messa a null ed
eventualmente liberata dal garbage collector.
-- 
Giambo - Occhio al filtro antispam _e_ alla whitelist !



Ciao,
non e' scorretto, ma e' inutile ed uno spreco di elaborazione.
Come spero tu sappia, quando scrivi una JSP, essa viene convertita in una
servlet, la servlet viene compilata, ne viene creata un'istanza, ed ogni
volta che l'URL corrispondente alla JSP viene richiesto, vengono chiamati
dei metodi della servlet.
Le differenti parti della pagina JSP diventano, a seconda dei casi,
attributi o metodi della classe della servlet.
In particolare, il codice che hai scritto tu viene inserito tutto in un
metodo della servlet, quindi le varibili (a e a1) che hai definito non
sono altro che delle variabili locali del metodo. Quindi esistono solo
durante l'esecuzione del metodo e cessano di esistere alla sua
conclusione. Percio' non c'e' bisogno di una "nullificazione" esplicita,
perche' comunque quegli oggetti non avranno piu' nessuna variabile che si
riferisce ad essi, e potranno essere "preda" del garbage collector.
-- 
Lucio Benfante
Java User Group Padova: 
http://www.jugpadova.it
Brainbench MVP for Java 1: 
http://www.brainbench.com
MyTranscript: 
http://www.brainbench.com/transcript.jsp?pid=167064

 eventualmente liberata dal garbage collector.
Se con "pagina" intendi l'istanza della servlet corrispondente alla JSP,
no, non avviene cosi'.


 è una cosa troppo puntigliosa o è una buona norma di programmazione???
out.println( (new StringBuffer(
                      new String("a"))).append(
                      new String("a1")) );
se le ho contate giuste, potrebbe essere un esempio di alternativa che
ottimizza l'uso della memoria.
annullare i riferimenti(mi avete convinto non li chiamo + pointer se no mi
linciate)serve di rado solo se hai un algoritmo particolare, ma
probabilmente se ti serve veramente hai pensato male le classi, infatti in
OOP dovrebbero esserci oggetti picccoli, metodi brevi, flusso rapido e
pulito.
Occhio che String e' l'unica classe "strana" e non la userei mai per fare
prove concettuali.
Nicola
 
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 eventualmente liberata dal garbage collector.
dunque appena dopo che "è stato inviato l'ultimo byte della  pagina
jsp dall'interprete" i riferimenti agli oggetti vengono perduti?
e se (ragionando per assurdo) la pagina  contenesse molto codice e
quindi ci volesse unpo' prima che l'interprete la interpreti tutta non
converrebbe liberare da codice i riferimenti senza aspettare che la
pagina venga interpretata interamente?
quello che mi avete detto per la pagina jsp vale anche per una singola
applicazione java che faccio girare da console(ad esempio la tipica
classe con cui si inizia Hello.java)?
nel senso una volta che l'interprete ha finito il suo
lavoro(interpretare la classe ) vengono liberati i riferimenti???
grazie e scusate se ho detto magari delle imprecisioni(magari anche
delle castronerie)

 lavoro(interpretare la classe ) vengono liberati i riferimenti???
Una jsp e' una servlet che viene eseguita da Tomcat o altro servlet
container
TOmvat a sua volta e' una normale applicazione col main()
quindi alla fine e' sempre la stessa broda.
Tu non devi preoccuparti mai di liberaere la memoria perche' cosi' e' fatto
java. All'inizio quando venivo dal C++ non mi andava giu' sta cosa, e molti
come me, abituati come eravamo a bestemmiare contro gli handle abbandonati.
1. Fidati del Gc come un credente si fida del suo Dio
2. e' rarissimo che una classe rimanga referenziata, cio' di solito avviene
quando usi variabili di istanza come variabili globali
all'applicazione(stile basic), ma questo e' un problema di ogni linguaggio,
di tecniche di programmazione insomma + che una specificita' di Java
per rispondere poi in particolare alla tua domanda. nella servlet e'
effettivamente ancora + safe il discorso memoria che viene gestita dal
container, rispetto alla main. Occhio pero' che li si posta il problema
dell'ottimizzazione a livello di "Session" + che a livello di VM.
ciao


 riferisce ad essi, e potranno essere "preda" del garbage collector.
ok Lucio, grazie.
e allora se mi creo un'applicazione(una classe java) tipo:
public class Esempio{
   public static void main(String[] args){
            String a =new String("a");
            System.out.println(a);
            ...codice molto complesso(quindi lungo da eseguire)
            che non utilizza + la stringa a...
 
 
   }
}
ecco in questo caso non sarebe giusto (prima di eseguire il codice
dopo il System.out.println(a);) mettere a=null???
in una jsp quale potrebbe essere un esempio simile???

 in una jsp quale potrebbe essere un esempio simile???
ma lungo quanto? si auspica non più di un paio di secondi, oltre il quale si
rende necessario ripensare alla struttura della pagina...
dacci retta... nullificare i riferimenti inutilizzati è solo una perdita di
tempo (in java).
-- 
Fermiamo Scientology prima che sia troppo tardi!!!
http://xenu.com-it.net
 - 
http://xenu.freewinds.cx/


 no, non avviene cosi'.
Eppure son convinto di aver letto da qualche parte che le JSP, a
differenza dei servlet, vengono istanziate e distrutte ogni volta.
Purtroppo non trovo piu' il testo in questione :-/ ...


 tempo (in java).
A meno che non possano produrre dei veri e propri memory leak, cosa
perfettamente possibile anche in Java. In tal caso la nullificazione
e' necessaria. Ma con le variabili automatiche non mi pare che si
possa provocare niente del genere.




..e non credo proprio che lo troverai ;-)


 Purtroppo non trovo piu' il testo in questione :-/ ...
Cerca, cerca... ;-)
E' un po' improbabile, visto che una volta compilati *sono* dei servlet.

 dopo il System.out.println(a);) mettere a=null???
E' abbastanza inutile. Con ogni probabilità finchè non è finita 
l'elaborazione il gc non libererà la memoria.

Dunque intanto vi ringrazio per l'aiuto.
La mia è solo una curiosità, non voglio certo mettermi a fare il
sofisticato (so a mala pena scrivere 2 righe di codice); diciamo che
ragionavo per assurdo.
Alla fine mi avete cmq detto che"... e' rarissimo che una classe
rimanga referenziata, cio' di solito avviene
quando usi variabili di istanza come variabili globali
all'applicazione..." e che "...il codice che hai scritto tu viene
inserito tutto in un metodo della servlet, quindi le varibili (a e a1)
che hai definito non sono altro che delle variabili locali del metodo.
Quindi esistono solo durante l'esecuzione del metodo e cessano di
esistere alla sua conclusione."
Mi sembra dunque di capire(scusatemi continuo a ragionare per assurdo
solo x poter togliermi questa curiosità) che se istanzi un oggetto
della classe A che ha delle variabili di istanza(e magari tra queste
variabili di istanza ci sono degli oggetti Stringa o altri oggeti)
tali variabili di istanza non cessano di esistere fintanto che non
viene eseguito tutto il codice del metodo main della classe (ho visto
che si definisce classe driver) che contiene l'oggetto della classe A;
immagino che lo stesso accadrà quando tramite jsp dai vita ad una
servlet che contiene delle variabili di istanza(in questo caso penso
che tali variabili di istanza cesseranno esistere quando è stata
eseguita la pagina).
E' ovvio poi che magari creare delle classi simili è errato ma vorrei
sapere se accade come ho detto io o meno, per capire se la cosa mi è
chiara.
(mandatemi pure al diavolo)

 eseguita la pagina).
Il problema è in come hai scomposto il task che fai eseguire al metodo 
main. Primo appunto: fai un pò di confusione tra Classi, istanze e 
metodo main. Soprattutto se da una parte parli di Servlet e dall'altra 
di metodo main.
Il main è un metodo come qualunque altro, l'unica differenza è che viene 
invocato dalla VM quando esegui una classe.
Cerco di interpretare quanto scrivi riportandolo in "pseudocodice":
class A {
   public static void main(String[] args) {
                  // poteva essere un altro metodo
     B var = new B(); // B è una classe le cui istanze occupano molta
                      // memoria
     /*
         ... utilizzo della variabile "var"
     */
     /*
         ... codice che non utilizza più var e che impiega molto tempo
         per terminare ...
     */
   }
}
Quì la faccenda andrebbe scomposta meglio. Un esempio:
class A {
   public static void main(String[] args) {
      fase1();
      fase2();
   }
   private static void fase1() {
     B var = new B();
     /*
       ... utilizzo della variabile "var"
     */
   }
   private static void fase2() {
     /*
         ... codice che non utilizza più var e che impiega molto tempo
         per terminare ...
     */
   }
}
Una volta terminato il metodo "fase1" l'istanza della classe B non è più 
referenziata da alcuna variabile e quindi può essere "garbage collected".
Tornando al discorso delle JSP/servlet il discorso è analogo. Fare 
elaborazioni lunghe all'interno del codice di una JSP è sbagliato. Se la 
tua applicazione richiede questo la soluzione sta nell'estrarre tali 
elaborazioni ponendole o in classi di utilità o, meglio ancora, 
eseguendole prima di passare il controllo alla JSP (e qui' ti consiglio 
il tutoria della sun perché il discorso si fa lungo).
Andrea

Rispondo al post di Andrea:
classi istanze e main penso mi siano abbastanza chiari, l'unica cosa
che mi sfugge è cosa sia(oppure forse non so l'acronimo)il Gc di cui
parla n.n
Grazie x aver interpretato(direi abbastanza corretamente) il mio
codice con questa classe:
class A {
   public static void main(String[] args) {
                  // poteva essere un altro metodo
     B var = new B(); // B è una classe le cui istanze occupano molta
                      // memoria
     /*
         ... utilizzo della variabile "var"
     */
     /*
         ... codice che non utilizza più var e che impiega molto tempo
         per terminare ...
     */
   }
}
e grazie anche per avermi dato dei suggerimenti su come riprogrammarla
meglio.
Il fatto è che io facevo un esempio(ok è sbagliato ma è un esempio); 
volevo appunto far notare che in un esempio simile  var(istanza delle
classe B)esiste fino al termine dell'applicazione e che in un caso
simile sarebbe quindi + opportuno metterla a null subito dopo averla
usata(almeno cosi ho pensato).
Poi sul fatto che un'apllicazione simile sia programmata da schifo ti
do ragione ma era solo x fare un esempio.
Spero di essere stato chiaro, non volevo creare una discussione cosi
barbosa.
grazie

 usata(almeno cosi ho pensato).
Dato l'esempio che hai fatto e visto i problemi dell'occupazione di
memoria, se la tua domanda è "mettendo a null la variabile dopo averla
usata le cose funzionano meglio?" la risposta è si, non bene ma meglio
si.
Ma se la tua domanda è "come faccio a risolvere il problema
dell'occupazione di memoria" la risposta non è "metti a null le
variabili" ma "riorganizza il codice in modo che questi problemi non si
presentino per niente".
Andrea

 Andrea
grazie, chiudo seno mi spari, lo vedo dal tono

 grazie, chiudo seno mi spari, lo vedo dal tono
No, no, scusami.
E' che dopo una giornata a passata a rispondere al telefono per 
risolvere i problemi piu' assurdi si vede che ho fatto trasparire la mia 
insofferenza anche con chi non se la meritava: dovrei evitare di 
rispondere sul newsgroup quando arrivo a questo livello ;-)
Andrea

...

ma no sei stato gentilissimo