Dobry den,

tem, kteri pochybovali nebo pochybuji o tom, kdy se uvolnuji lokalni promenne nebo je proste jen zajima prace s pameti, doporucuji posledni dva News Lettery od Heinze Kabutze.

News Letter 173 obsahuje hezkou hadanku:
http://www.javaspecialists.eu/archive/Issue173.html

News Letter 174 obsahuje jeji reseni:
http://www.javaspecialists.eu/archive/Issue174.html

Jde o problem podobny tomu, ktery jsme zde diskutovali v unoru.

Z.T.
--
Zdenek Tronicek
Department of Computer Science and Engineering
Prague                   tel: +420 2 2435 7410
http://cs.felk.cvut.cz/~tronicek


Cituji Zdenek Tronicek <[email protected]>:

Dobry den,

myslim, ze pokud chcete porozumet tomu, proc nebyl objekt foo odstranen z pameti, je nutne se trochu podivat na bytecode. V Jave funguje alokace lokalnich promennych tak, ze pri VSTUPU DO METODY se na zasobniku naalokuje prostor dostatecne velky na to, aby se tam vesly vsechny promenne deklarovane v teto metode. Tento prostor se deli na tzv. sloty. Kazdy slot ma 32 bitu. Promenne typu byte, char, short, int, boolean, float a reference zabiraji 1 slot, double a long 2 sloty.
No a kazda lokalni promenna je pak identifikovana cislem slotu.
Pro GC je dulezite to, ze prostor pro lokalni promenne existuje po celou dobu vykonavani metody. Tzn., ze i kdyz opustime blok, v nemz byla promenna deklarovana, neznamena to, ze je fyzicky (v pameti) zrusena. Jinymi slovy: ukazatel na objekt vytvoreny prikazem new Foo(null); je ulozen v nekterem slotu a GC nepozna, ze jej muze dealokovat, protoze nema informaci o tom, ktere sloty jsou aktualne pouzivane.

Principialne by bylo mozne, aby prekladac generoval pri opusteni bloku instrukce pro nulovani vsech slotu, do nichz byly ulozeny promenne lokalni v tomto bloku, ale sunovsky javac to nedela a rekl bych, ze to nedelaji ani jine prekladace. Ve vyjimecnych pripadech by to sice pomohlo, vetsinou by to vsak byl znacny overhead.

Z.T.
--
Zdenek Tronicek
Department of Computer Science and Engineering
Prague                   tel: +420 2 2435 7410
http://cs.felk.cvut.cz/~tronicek


Cituji Dusan Zatkovsky <[email protected]>:

Ahoj.

Kedze som v jave novy a prechadzam do nej z C++, obcas sa pri programovani
pozastavim nad nejakou vecou, o ktorej viem, ze tak nejak funguje, ale aby
som mal pokojne spanie, musim si to osahat vlastnymi rukami.

Prave som napisal nejaku class-u, ktora obaluje urcite podclassy a poskutyje
urcitu ucelenu funkcionalitu. Tie jej podclassy rozne ukazuju sami do seba,
medzi sebou a tak podobne, proste o sebe vedia. A tak sa mi hlavou zacali
tocit otazky okolo garbage collectoru, platnosti objektov, case ich uvolnenia
z pamati a tak podobne.

A kedze som bol byvalym kolegom ( zdravim Ta Nhac :) ) presviedsany, ze reci
okolo javy a jej pamatovej nenazranosti su nezmysly, vyrobil som si rovno
maly test:

// obycajna class-a. Vypisom testujem cas jej odstranenia z pamati
// urdzuje odkaz na svoju nadradenu classu, pretoze obe budem nejak
// zapuzdrovat do jedneho celku a vyuzivaju medzi sebou svoje sluzby

public class Foo {

   private Stuff stuff;

   public Foo ( Stuff s ) {
       this.stuff = s;
   }

   @Override
   protected void finalize() {
       System.out.println("finalize Foo");
   }
}


// nejaka dalsia classa
public class Stuff {

   public Foo foo = new Foo ( this );

   @Override
   protected void finalize() {
       System.out.println("finalize Stuff");
   }
}


public static void main(String[] args) {

       System.out.println("start");
       {
           // vytvorim Foo
           Foo f = new Foo(null);
           // vytvorim Stuff, ten si vytvori dalsie Foo
           Stuff s = new Stuff();
           // f = null
       }

       // tu uz neexistuje ani Foo f, ani Stuff f, mozu byt zmazane

       while ( true ) {
               System.out.println("aaa");
               Runtime.getRuntime().gc();
               Thread.sleep(2000);
       }
   }
}


Kupodivu, vystupom programu bol nasledovny vypis:
        start
        aaa
        aaa
        aaa
        ...

Po pol hodine som to nechapajuc breakol.

Odkomentoval som to "f = null"

Vystup:
        start
        aaa
        finalize Foo
        aaa
        aaa
        aaa
        ...

Toto som nechal bezat par minut. Garbage collector ten Stuff nie a nie zmazat.

Priznam sa, ze to uplne nechapem, pretoze za prvou zlozenou zatvorkou }
straca "Stuff s" platnost a nema dovod viac existovat v pamati.

Mna by zaujimalo, kedy ho gc uvolni, pretoze pokial bude mat Stuff 2GB, bude
aplikacia bezdovodne kradnut systemu 2GB pamati na bordel, ktory uz nikdy
nepouzije, boh vie na aku dlhu dobu.

Diky.

--
Dusan






Odpovedet emailem