Kedy dojde k odstraneniu objektu?
Zdenek Tronicek
tronicek na fel.cvut.cz
Úterý Únor 24 17:50:51 CET 2009
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 <msk.conf na gmail.com>:
> 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
>
Další informace o konferenci Konference