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