[Java] how to implement a 'destructor'

Pagina: 1
Acties:

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
klein probleempje:

java kent zower ik weet geen destructors zoals C++. maar nu heb ik het probleem
dat ik een class heb die op een 'static class' (een global dus) iets (maakt niet uit) genereert. Wat ie genereert wordt bijgehouden en maintained door die globale (ok hij houd CachedXPathAPI's bij ;) ) maar die objecten kunnen erg groot zijn en sommige kunnen 'delete' worden als het programma zeker weet dat ze niet meer nodig zijn. Mijn class creert dus zo'n Cache maar die mag weg nadat het object wordt 'gedelete' - zodoende kan ik de cache vrijlaten.

Ik heb ergens wel iets gevonden ivm finally maar niets over hoe je dit zou moeten implemteren op Class-niveau.

visueel:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
tClass = new myClass("some xml");

//de constructor doet dan
public myClass(String xml)
{
   gXMLCaches.addNewXPathCache(xml); //returned niets want maakt niet uit
}

//de rest van het programma kan dus nu aan die cache (is transparent)

//op een bepaalt punt weet ik 100% zeker dat ik de cache niet meer nodig heb
//dit is wanneer tClass wordt verwijderd (meestal gaat ie gewoon out-of-scope)
//dan zou die dus ergens in de 'destructor':

gXMLCaches.deleteXPathCache(aNode from my cache...)


dat ik voordat hij out of scope gaat kan ik natuurlijk dit manueel doen maar ik doe geen OOP om dat zelf bij te houden... iemand een ideetje?

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Java klassen hebben inderdaad geen destructors, maar wel finalizers. Zie de finally methode van Object.

Je kunt ook Soft/WeakReferences (in java.lang.ref) gebruiken voor je cache. Dan wordt het geheugen automatisch vrijgegeven als er verder geen referenties naar een object zijn.

[ Voor 3% gewijzigd door marcusk op 28-02-2003 19:51 ]


  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
nou dat was eenvoudiger dan gedacht :) bedankt. 2de opties werkt niet echt - de caches zitten in een HashMap en ik denk niet dat java.lang.ref even een delete op die HashMap loslaat :) alhoewel er een WeakHashMap bestaat... i'll keep it simple thx

  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
hobbit_be schreef op 28 februari 2003 @ 19:41:
klein probleempje:

Ik heb ergens wel iets gevonden ivm finally maar niets over hoe je dit zou moeten implemteren op Class-niveau.
<code> public void finalize()</code> overriden uit Object. Deze methode zal aangeroepen worden door de VM voordat hij de boel gaat purgen. Het is mogelijk om in finalize dus de destructie te stoppen :)
dat ik voordat hij out of scope gaat kan ik natuurlijk dit manueel doen maar ik doe geen OOP om dat zelf bij te houden... iemand een ideetje?

Je hebt niet echt veel keus :) Je bent zojuist een punt tegen gekomen van garbage collected languages :P

Punt is namelijk dat je wel de boel in finalize() kan gaan implementeren maar dan ga je stuk op 2 dingen
1) Het is goor :P Finalize() ruimt dingen op. De functie is puur alleen bedoeld voor low level dingen. Andere classes die je class gebruiken en opeens een state change krijgen zullen dat niet verwachten :)
2) finalize() wordt in de sommige apps nooit aangeroepen. De JVM gaat pas de garbage collector actief maken als er een goede reden is om dat te doen ( ie als er dus geheugen nodig is ). Daar moet je dus niet op gaan vertrouwen.

Je hebt dus twee opties:
1) Het zelf commando geven tot opruimen uit de cache. Dit vind ik erg netjes omdat je je object generieker maakt :)
2) WeakRef gebruiken of een WeakHashMap. Hierdoor haal je de controle over de cache helemaal weg bij je class en leg je die bij het cachende object. Lijkt me helemaal mooi :)

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
jesus! :) wel bedankt voor de warning: nu snap ik ook ineens waarom JBuilder steeds groter wordt en dan na een tijdje weer helemaal 'krimpt'. Die garbage collector is dus blijkbaar maar op een lage 'priority'... verdomme moet ik die WeakHashMap gaan implementeren gelukkig dat de hele XPath wrapper daardoor niet veranderd... (wat een beetje design al niet kan doen :). Eigenlijk wel gek dat er dan geen 'delete' bestaat in Java. OK het is niet nodig maar het doet eigenlijk geen kwaad. (een beetje zoals de pre-fetch in PIII+ processors)... ik hoop ten zeerste dan C# dit wel heeft? anders blijf ik lekker bij C++ in het vervolg ...

  • MisterData
  • Registratie: September 2001
  • Laatst online: 09:53
hobbit_be schreef op 28 February 2003 @ 20:50:
ik hoop ten zeerste dan C# dit wel heeft? anders blijf ik lekker bij C++ in het vervolg ...
In C# kun je zelfs kiezen of je de GC aan wilt hebben of niet.... wat een luxe he ;)

Goede quote van (ik geloof) MSalters: "If there's no garbage in a language, you don't need to collect it" :)

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
MisterData schreef op 28 February 2003 @ 21:57:
Goede quote van (ik geloof) MSalters: "If there's no garbage in a language, you don't need to collect it" :)
_/-\o_

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Voor meer informatie over gc in java zie: http://www.artima.com/insidejvm/ed2/gc.html

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
great article!!!

maar call me stupid maar nu begrijp in nog steeds niet hoe ik het met een WeakHashMap zou moeten oplossen :)...

mijn cacheable object hangt af van het bestaan van een ander Object...

aRealObject (XMLDocument) -> aCachedObject (Parsed DTM Document)...

stel ik add:

gWeakHashMap.put(aRealObject, aCachedObject)...

stel ergens verder in het programma word aRealObject weak en moet aCachedObject verwijderd worden. Maar doet ie dat? of moet ik aCachedObject ook nog eens WeakReference-n? dus:

gWeakHashMap.put(aRealObject, new WeakReference(aCachedObject))...

ik weet namelijk niet of aCachedObject ergens een reference naar aRealObject bijhoudt... (dat is implementatie dependant)...

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Lees dat stuk nog even goed door, er staat echt in uitgelegd hoe je dit kan oplossen. Laat het even goed bezinken :)

[ Voor 16% gewijzigd door Alarmnummer op 01-03-2003 12:57 ]


  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
ik denk dat mijn filterke te fijn is - en er komt niets door :) zal er straks even terug op komen... :)

edit:

ok dus het is gewoon

gWeakHashMap.put(aRealObject, aCachedObject);

aangezien aCachedObject afhangt van het bestaan van aRealObject.

MAAR als aCachedObject WEL een reference heeft van aRealObject dan wordt aRealObject nooit weak and verdwijnt nooit dus snap ik er weer niets van... sniff sniff

in de API staat dat the value idd geen ref mag hebben van de key... dus moet je
hem dus WeakReferencen... maar verdwijnt de value dan niet? ik denk dat dit wel het meest onduidelijke deel van Java is dat ik ben tegengekomen :)

edit 5:

now it seems WeakHashMap doesn't work the same under Linux and Windows (under Linux it quickly gives out Of memory) while Windows happily runs along. I'll do it bloody manually :)

en zelfs in Xindice (die er ook gebruik van maakt voor zijn cache) is dit een bug en hebben ze speciale handler code moeten schrijven voor 1.4 and Linux - waar staat ook weer dat Java 100% cross-platform is? - hun oplossing is nog moeilijker dan manual release...

edit 6:

en nu blijkt dat SoftReferences (een SoftHashMap is veel beter voor een cache) ok 'sommige' JDK implementation gewoon als WeakReferences worden gebruikt. maw ook OutOfMem - errors --- wat een geklooi allemaal..

[ Voor 122% gewijzigd door hobbit_be op 01-03-2003 13:58 ]

Pagina: 1