Presne toto som vcera pozoroval na seminari z Javy.
Mali sme priklad, ked trieda mala po ukonceni aplikacie serializovat svoje
data
na disk.
Najzjavnejsi a najjednoduchsi napad bolo pouzit finalize(). V
inteligentnejsich pripadoch
by sa totiz zadanie skomplikovalo a na to nebol cas.
Polovici ludi to zbehlo a druhej polovici nie.
Aby sme to nakoniec nekomplikovali, rozhodli
sme sa volat finalize() manualne. Viac som po tom nepatral.
Ked sa na to pozeram, opat sa ukazalo, ze finalize() by v podstate
malo byt zakazane, lebo posobi len neplechu.
Vdaka za vysvetlenie.
RN
On Wed, 25 Feb 2009 10:44:41 +0100, Lukáš Zapletal <[email protected]>
wrote:
Necetl jsem to vse cele, ale je nutne si uvedomovat, ze GC nemusi
objekt uklidit vubec! Paklize dojde k ukonceni programu, nez dojde
pridelena heap a GC se "nerozhodne" vubec pro uklid, tak se javovsky
proces ukonci a vrati cely blok pameti do OS.
Tj k volani finalize nedojde vubec.
LZ
2009/2/24 Tomas Studva <[email protected]>:
To kedy sa dealokovalo f, zaviselo od velkosti pola, cize ci sa este
pred
cyklom automaticky spustilo gc.
Treba si vsak uvedomit ze kompilator nemoze takmer vobec ovplyvnit
dealokaciu - ak by bol predposledny prikaz bloku volanie nejakej
metody, tak
uz nik nevie co sa stalo. Nejako vsak ten gc vie ze na f uz nic
neukazuje,
alebo je v inej generacii ako stuff. Napada mi reference counting, ale
to sa
zevraj nepouziva v gc-ckach (viem ale ze ref-count. napr. pouziva
Cocoa).
Zdenek Tronicek wrote / napísal(a):
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.
--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/