Newsgroup: it.comp.java
Titolo: Metodi static e garbage collector

Salve a tutti,
ho una questione che mi sembra fondamentale, ma a cui non trovo
risposta in giro per il web...
Poniamo ad esempio una classe con un  qualsiasi metodo statico :
class myClass {
  public static String add (String _a, String _b) {
    String c = _a+_b;
    return c;
  }
}
Come viene trattata la variabile c?
1)Ad ogni invocazione di myClass.add viene creato in memoria un
oggetto statico nuovo?
2)Il compilatore considera c come variabile statica (e quindi unica)
appartenente al metodo?
Nel caso 1) una ripetuta invocazione del metodo porterebbe ad un
veloce out-of-memory?
Nel caso 2)  esisterebbe una sola e unica istanza dell'oggetto c;
ipotizzando che due o più thread invocassero ripetutamente il metodo
cosa potrebbe succedere allo "stato" della variabile c? Divenire
incongruente essendo "condivisa" tra più thread? (ovviamente potrebbe
sincronizzare, ma sto facendo solamente una speculazione...)
Qualcuno mi può aiutare?

 writes:
S> Salve a tutti, ho una questione che mi sembra fondamentale, ma a cui
S> non trovo risposta in giro per il web...  Poniamo ad esempio una
S> classe con un qualsiasi metodo statico :
S> class myClass { public static String add (String _a, String _b) {
S>     String c = _a+_b;
S>     return c;
S>   }
S> }
S> Come viene trattata la variabile c?
S> 1)Ad ogni invocazione di myClass.add viene creato in memoria un
S> oggetto statico nuovo?  2)Il compilatore considera c come variabile
S> statica (e quindi unica) appartenente al metodo?
[... omissis ...]
S> Qualcuno mi può aiutare?
E' una variabile locale. Esiste solo durante l'esecuzione del metodo.
Questa è  una cosa fondamentale, avere  dei dubbi su questo  punto non è
una bella  cosa, vuole  dire che devi  ricominciare daccapo  a studiarti
tutto sforzandoti di dimenticare quello che hai studiato male...
Spiacente che la risposta non sia piacevole, ma la situazione è questa.
-- 
 /\           ___                                    Ubuntu: ancient
/___/\_|_|\_|__|___Gian Uberto Lauri_____               African word
  //--\| | \|  |   Integralista GNUslamico            meaning "I can
\/                   e coltivatore diretto               not install
                               di software                   Debian"
a Cesare avrei detto di scrivermi | I would have told Caesar to write
a 
fn...@rat.vg
                    | me at 
fn...@rat.vg

 veloce out-of-memory?
relativamente al comportamento di quel metodo, assolutamente no.  la
variabile c è locale quindi una volta terminata l'esecuzione del
metodo esce dallo scope e quindi non referenzia più l'oggetto, per
quanto concerne il metodo l'oggetto può essere candidato al garbage
collector. poi, siccome il metodo ritorna la stessa istanza, che sia
candidato o meno al gc dipende dal chiamante.

Grazie a tutti, avete completamente dissolto tutti i miei dubbi...
Ovviamente essi si rifanno ad una domanda meno specifica che mi
assilla
da qualche tempo (cercherò di essere sintetico) :
Ho un progetto con dei ws e dei thread residenti (che esistono per
tutta
l'esecuzione). Ognuno di questi thread (che possono essere anche 9-10)
deve ottenere ogni circa 1 secondo delle informazioni sullo stato di
alcuni
componenti dell'applicativo (componenti fondamentali e globali al
progetto e quindi,
a mio modo di vedere statiche, anche se possono cambiare "stato"). Nel
complesso
dell'architettura SoA è chiaro che la soluzione sarebbe un servizio
interno dedicato...
Ovviamente l'overhead derivante dall'uso di un servizio per reperire
un dato
che alla fine dei conti è globale e locale mi appare comunque uno
"spreco"...
per questo ho introdotto un metodo statico. Ma purtroppo esso conduce
inevitabilmente l'applicazione all'out of memory....per questo mi sono
sorti questi dubbi...
Ma allora quale è la risposta? Servizio o metodo statico? o
salvataggio nella
memoria di "Applicazione"?

memoria di "Applicazione"?
E' praticamente impossibile dare una risposta senza conoscere meglio 
l'architettura
di cui parli... domanda però "cattiva" (fatta senza voler essere offensivo, 
però!!!): a te sembra normale
che l'architettura di cui parli affondi con un "out of memory" perchè ci 
sono 10 thread che
ne interrogano lo stato ? A me, onestamente - ma non voglio fare il Solone - 
sembra assurdo;
fossi in te cercherei in primis di capire da dove derivi il problema di 
memoria.
Da un punto di vista concettuale, IMHO, una variabile di ambiente globale 
può correttamente
essere una variabile statica, condivisa dall'applicativo: sul come 
interrogarla, beh, dipende da troppi
fattori tra cui, soprattutto, lo scopo di questa interrogazione ed il tipo 
del progetto che stai realizzando.
Scorpio.

Ciao,
certo, non mi sembra certo normale che sia lanciata un'eccezione di
out of memory...ma come può accadere?
Mi consigliate qualche tool utile allo scopo? Come è possibile
rilevare errori di questo tipo?
Più in generale come può un programmatore incauto provocare un out of
memory, ingannando il garbage collector?

 memory, ingannando il garbage collector?
Non è detto (anzi, è decisamente improbabile) che un out of memory sia 
causato da un errore del gc, è molto più probabile che sia un errore del 
programmatore.
Per identificarlo "basta" un debug, che si può effettuare con gli n-mila 
strumenti a disposizione o con delle semplici print nei punti sospetti 
del codice.
Ciao,
Paolo

 writes:
S> Ciao, certo, non mi sembra certo normale che sia lanciata
S> un'eccezione di out of memory...ma come può accadere?  Mi consigliate
S> qualche tool utile allo scopo? Come è possibile rilevare errori di
S> questo tipo?  Più in generale come può un programmatore incauto
S> provocare un out of memory, ingannando il garbage collector?
Oltre  alle  sagge  parole  di  Xon,  aggiungo  qualche  centesimo  alla
discussione.
Oltre  agli   errori  del   programmatore,  ci  sono   anche  situazioni
contingenti, è  necessario avere in memoria  più di 64 Mega  di dati. In
questo caso  e utile il  flat -Xmx[size], ad  esempio il codice  sotto è
stato fatto per un paio di prove con size settato ad oltre un giga...
	/**
	 * <code>main</code> 
	 *
	 * @param args a <code>String</code> 
	 */
	public static final void main(final String[] args) {
		String foo = "foo";
		String bar = "bar";
		String clop[];
		long a, b, c;
		for (int i = 0; i < 10; i++) {
			a = System.currentTimeMillis();
			clop = new String[4000000];
			b = System.currentTimeMillis();
			System.out.println(b-a);
			for (int j = 0; j < 4000000; j++) {
				clop[j]=foo+bar+" "+foo+bar+" "+j;
			}
			c=System.currentTimeMillis();
			System.out.println(c-b);
			System.out.println();
		}
	}
In  ogni  caso  un  programmatore   deve  essere  in  grado  di  stimare
l'occupazione di memoria (almeno quella worst case).
Nota di  folklore: in questi casi  chiamare il garbage  collector non ha
senso.  Come diceva un  simpatico libro,  se la  JVM potesse  parlare in
questi casi ti guarderebbe  con faccia seccato-ironica dicendo "Wow, che
idea geniale" dato  che a quel punto "ha già  combattuto fino alla morte
per trovarti il pezzo di memoria libera"


 memory, ingannando il garbage collector?
sui possibili casi ci si può sbizzarrire con la fantasia.