Kedy dojde k odstraneniu objektu?
Zdenek Tronicek
tronicek na fel.cvut.cz
Úterý Únor 24 22:26:59 CET 2009
Ja jsem popisoval, jak se chova JVM za "normalnich" podminek. V
okamziku, kdy zacne dochazet pamet, zacne JVM drsne optimalizovat. A
ze to umi, lze videt na tomto prikladu (z Vaseho kodu jsem vypustil
blok):
System.out.println("start");
// vytvorim Foo
Foo f = new Foo(null);
// vytvorim pole Stuff
Stuff[] theStuffs = new Stuff[100000];
for (int i = 0; i < theStuffs.length; i++) {
theStuffs[i] = new Stuff();
}
// nez se dojde sem, je po objektu f
while (true) {
System.out.println("aaa");
Runtime.getRuntime().gc();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Na mem pocitaci dojde k dealokaci objektu f jeste drive, nez se
vstoupi do smycky while. Jak k tomu muze dojit? Java neco takoveho
neumoznuje, jde ciste o optimalizaci JVM.
Mimochodem, myslim, ze tohle je na hranici toho, co jeste lze delat,
protoze kdyby nejaky program spolehal na to, ze objekt nemuze byt
dealokovan pred koncem platnosti promenne f (tj. pred koncem metody),
nebude fungovat.
Pokud jde o ty lokalni promenne, tak ve vypise javap je jejich pocet
za retezcem Locals= a po dobu vykonavani metody se tato hodnota nemeni.
Z.T.
--
Zdenek Tronicek
Department of Computer Science and Engineering
Prague tel: +420 2 2435 7410
http://cs.felk.cvut.cz/~tronicek
Cituji Tomas Studva <tstudva na gmail.com>:
> Ahoj,
> podla mna uz z vasho testovania vyplynulo, ze gc si da namahu
> uvolnit pamat co i len aj po jednom objekte - pripad ked ste
> nastavil f na null.
> Ja som skusil nastavit "s" na null a dopadlo to podla ocakavania, gc
> zrusil "s" aj obsiahnute "s.foo". Povedat ze gc uvolnuje lokalne
> premenne metod az po opusteni metody je hlupost, lebo potom pamatovo
> narocne metody by zjedli pamat aj keby uvolnovali referencie.
>
> A tak som skusil toto:
>
> System.out.println("start");
> {
> // vytvorim Foo
> Foo f = new Foo(null);
> // vytvorim pole Stuff
> Stuff[] theStuffs = new Stuff[1000000];
> for (int i = 0; i < theStuffs.length; i++) {
> theStuffs[i] = new Stuff();
> }
> }
> // tu uz neexistuje nic
> while ( true ) {
> System.out.println("aaa");
> Runtime.getRuntime().gc();
> try {
> Thread.sleep(200);
> } catch (InterruptedException e) {
> // TODO Auto-generated catch block
> e.printStackTrace();
> }
> }
>
>
> Samozrejme ze gc pracoval a finalizoval. Trochu srandovny bol vystup
> niekde v strede:
> finalize Stuff
> finalize Stuff
> finalize StuffException in thread "main" java.lang.OutOfMemoryError:
> Java heap space
> at java.lang.ref.Finalizer.register(Unknown Source)
> at java.lang.Object.<init>(Object.java:20)
> at Foo.<init>(Foo.java:6)
> at Stuff.<init>(Stuff.java:3)
> at Stuff.main(Stuff.java:18)
>
> finalize Foo
> finalize Foo
>
> Nebudem to analyzovat, lebo to nebol vhodny priklad, pole je predsa
> nieco ine ako lokalne premenne. Spravny priklad by bol vytvorit tu
> metodu s naozaj desattisickami lokalnych premennych(cez makro by to
> slo).
>
> T.S.
>
Další informace o konferenci Konference