Re: Re: Kdy pouzit Object.finalize()?

Jan Moravec hmor na seznam.cz
Čtvrtek Leden 28 20:55:19 CET 2010


To je sice pravda, ale asi jen ve specifikaci... Minimalne Suni JVM pri System.gc zahaji Full GC (prakticky overeno na 1.6 na Win i Linux). Konkretne jsem na to narazil pri exportu reportu pres JasperReports, ktery kdesi v nitru vola System.gc :( JVM pak pri generovani reportu v cca 20 soubezne pustenych threadech totalne vyradila cely slavny dual quad-core stroj a v GC logu bezel jeden Full GC za druhym. Po disablovani System.gc problem samozrejme zmizel. 

=== http://java.sun.com/docs/hotspot/gc1.4.2/  (u novejsich JVM to je stejne) ===
Another way applications can interact with garbage collection is by invoking full garbage collections explicitly, such as through the System.gc() call. These calls force major collection, and inhibit scalability on large systems. The performance impact of explicit garbage collections can be measured by disabling explicit garbage collections using the flag -XX:+DisableExplicitGC.
===

Od te doby bez -XX:+DisableExplicitGC nic provozuji :) Osobne bych System.gc z API uplne vyradil, jelikoz jde proti logice GC, bohuzel je to tam od 1.0. No alespon deprecated kdyby to bylo...

Honza

------------ Původní zpráva ------------
Od: Arnošt Havelka <havelka na igsoft.cz>
Předmět: Re: Kdy pouzit Object.finalize()?
Datum: 28.1.2010 19:17:18
----------------------------------------
Ad "po zavolani System.gc se vzdy spusti Full GC") S tim bych si dovolil 
polemizovat. V materiálech SCJP uvádí, že vynutit GC nelze, resp není to 
garantováno. Sice o to můžeme požádat právě voláním tohoto příkazu, ale 
GC se může rozhodnout, že nic neudělá. Záleží tak silně na implementaci 
JVM (jak to mají napsané).

Arny

Zdenek Tronicek wrote:
> Dost odstrasujici pripad.
>
> Volani System.gc() by mel kazdy vedouci projektu zakazat. Krome nekolika
> specialnich situaci, jako jsou performance testy, stejne k nicemu neni a
> velmi casto nadela vice skody nez uzitku (po zavolani System.gc se vzdy
> spusti Full GC a dochazi k presunu objektu z young generace do tenured).
>
> Z.T.
> --
> Zdenek Tronicek
> FIT CTU in Prague
>
>
> Oto Buchta napsal(a):
>   
>> K metodě finalize() - jediný smysl má tehdy, pokud si člověk sám řídí
>> Garbage collector. Vím minimálně o jednom případě, kdy jsem tak musel
>> činit, neb knihovna, kterou jsem musel použít, byla tak příšerně
>> napsaná, že to ani jinak nešlo. Z licenčních důvodů jsem do ní nemohl
>> zasáhnout a tak jsem jenom naimplementoval jednoduchý wrapper kolem
>> jejich dao objektu, který jsem zaregistroval pro použití místo jejich.
>> Po skončení určité části knihovna zavolala GC a to byla jediná chvíle,
>> kdy jsem se dostal k informaci, že je komunikace právě v tomto stavu.
>> K tomu samozřejmě mají vlastní GC a mluví o tom jako o úžasné
>> vlastnosti, že si sami prý qůli rychlosti řídí GC :-( No blivajz.
>>
>> Dne 28. ledna 2010 13:24 Filip Jirsák <filip.jirsak na gmail.com> napsal(a):
>>     
>>> Přesně tak jsem to myslel - ne vyhodit výjimku ať ji zpracuje někdo
>>> jiný,
>>> ale zpracovat ji stejným způsobem, jako výjimky obvykle zpracováváte, s
>>> přihlédnutím k tomu, že se pohybujete na tenkém ledě metody finalize().
>>>
>>> Filip Jirsák
>>>
>>>
>>> Dne 28. ledna 2010 12:50 Kamil Podlesak <kamil.podlesak na gmail.com>
>>> napsal(a):
>>>       
>>>> Tady bych opravil: výjimku ve finalize() zapsat do logu, vyhodit ji
>>>> nemá moc smysl (to je právě jeden z problémů finalize: co se stane
>>>> když vyletí výjimka?)
>>>>
>>>> Jinak tuto praktiku vřele doporučuji, samozřejmě je pak nutné nechat
>>>> nějak automaticky sledovat (grepovat) aplikační log na produkci a
>>>> nalezené chyby opravovat.
>>>> Spoléhat na programátorskou disciplinu je _velmi_ deprecated :-)
>>>>
>>>> Kamil Podlešák
>>>>
>>>> 2010/1/28 Filip Jirsák <filip.jirsak na gmail.com>:
>>>>         
>>>>> Ještě doplním, že může být vhodné tu pojistku doplnit assertem, který
>>>>> upozorní na to, že někdo někde tu úklidovou metodu zavolat zapomněl.
>>>>> Záleží
>>>>> pak na kontextu, jestli tohle stačí, nebo jestli je k tomu potřeba si
>>>>> táhnout nějakou další informaci - typicky v konstruktoru si (pod
>>>>> assertem)
>>>>> vytvořit výjimku, uložit si ji, při zavolání close() ji vymazat a ve
>>>>> finalize() otestovat její přítomnost, a pokud výjimka existuje,
>>>>>           
>>>> vyhodit
>>>>         
>>>>> jí.
>>>>>
>>>>> S pozdravem
>>>>>
>>>>> Filip Jirsák
>>>>>
>>>>> --
>>>>> filip na jirsak.org
>>>>>
>>>>>
>>>>> Dne 28. ledna 2010 11:44 Zdenek Tronicek <tronicek na fit.cvut.cz>
>>>>> napsal(a):
>>>>>           
>>>>>> Aplikacni programator udela nejlepe, kdyz na finalize() zapomene a
>>>>>> misto
>>>>>> nej bude pouzivat metodu pro uklid a try + finally:
>>>>>>
>>>>>> InputStream is = ...
>>>>>> try {
>>>>>>  ...
>>>>>> } finally {
>>>>>>  is.close();
>>>>>> }
>>>>>>
>>>>>> Pokud jde o to, zda ma finalize nekdy smysl, tak ano: muze to byt
>>>>>> pojistka
>>>>>> pro pripad, ze programator zapomnel zavolat uklidovou metodu.
>>>>>> Programator
>>>>>> by na to ovsem nemel spolehat a mel by se snazit, aby kazdy objekt
>>>>>>             
>>>> po
>>>>         
>>>>>> sobe
>>>>>> uklidil.
>>>>>> Jinak ten clanek, ktery uvadis, je z roku 98. Takze to asi nebude
>>>>>> nejvhodnejsi zdroj.
>>>>>>
>>>>>> Z.T.
>>>>>> --
>>>>>> Zdenek Tronicek
>>>>>> FIT CTU in Prague
>>>>>>
>>>>>>
>>>>>> Ondra Medek napsal(a):
>>>>>>             
>>>>>>> Ahoj,
>>>>>>>
>>>>>>> navazuji tak trochu na predchozi thread. Jsem ted zmaten, jesli ma
>>>>>>> Object.finalize() smysl nebo by mel byt @Deprecated. Pokud ma
>>>>>>>               
>>>> smysl,
>>>>         
>>>>>>> tak kdy ho pouzit?
>>>>>>>
>>>>>>> V JDK 1.6 JavaDoc dokumentaci
>>>>>>>
>>>>>>>
>>>>>>>
http://java.sun.com/javase/6/docs/api/java/lang/Object.html#finalize%28%29
>>>>>>> stoji:
>>>>>>>
>>>>>>> "For example, the finalize method for an object that represents an
>>>>>>> input/output connection might perform explicit I/O transactions to
>>>>>>> break the connection before the object is permanently discarded."
>>>>>>>
>>>>>>> Clanek ja Javaworld
>>>>>>> http://www.javaworld.com/javaworld/jw-06-1998/jw-06-techniques.html
>>>>>>> tez radi ve finalize() uvolnovat systemove zdroje, ale pouze jako
>>>>>>> "fallback mechanism". (Coz mi presne sedi pro ten java.awt.Window
>>>>>>> problem).
>>>>>>>
>>>>>>> Progrepoval jsem JDK 1.6 zdrojaky a SUN se k finalize() asi stavi
>>>>>>> ambivalentne: nekde ho pouziva, nekde ne. Priklady pouziti:
>>>>>>> java.util.zip.ZipFile - zavira IO stream
>>>>>>> java.io.FileInputStream + java.io.FileOutputStream : zaviraji file
>>>>>>> descriptory
>>>>>>> ... a dalsi
>>>>>>>
>>>>>>> Nejvice je onen ambivalentni pristup videt na ImageInputStreamImpl
>>>>>>>               
>>>> a
>>>>         
>>>>>>> FileImageOutputStream z baliku javax.imageio.stream:
>>>>>>> ImageInputStreamImpl ma finalize(), ktere v podstate jen nastavi
>>>>>>> priznak isClosed = true
>>>>>>> FileImageOutputStream je potomek ImageInputStreamImpl a prepisuje
>>>>>>> finalize(), ve kterem nedela nic.
>>>>>>>
>>>>>>> Dale jsem nasel treba zakomentovany finalize(), ktery puvodne
>>>>>>> zavitral
>>>>>>> IO stream, v
>>>>>>>               
>>>> com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl
>>>>         
>>>>>>> s
>>>>>>> poznamkou, ze "It affects the performance greatly in multi-thread
>>>>>>> environment. ". Tedy ZipFile vesele IO stream zavira ve
>>>>>>>               
>>>> finalize(),
>>>>         
>>>>>>> kdezto CoreDocumentImpl  to ma zakomentovane.
>>>>>>>
>>>>>>> Diky
>>>>>>> Ondra Medek
>>>>>>>
>>>>>>>               
>>>>>           
>>>       
>>
>> --
>> Oto 'tapik' Buchta, tapik na buchtovi.cz, http://tapikuv.blogspot.com
>>
>>     
>
>
>   





Další informace o konferenci Konference