Lotus Notes / Domino Sonstiges > Java und .NET mit Notes/Domino
Speicherverwaltung Java + Lotus Notes Domino
Ralf_M_Petter:
Hallo Thomas!
Ich denke du hast auf Axel geantwortet. Aber hier nochmal zur Klarstellung. Meine Angaben bezogen sich auf Agenten und hier steht in der Agent FAQ ganz klar, dass man sich wenn man alle Objekte aus der Session des Agents gewinnt sich um Recycle keine Gedanken machen muß, ausser man erstellt soviele Objekte, dass man Memoryprobleme bekommt. Wenn der Agent beendet ist, kümmert sich Notes um das Recycle der Session. Genauso reicht es in einfachen Javprogrammen die keine Schleifen und ähnliches haben, am Ende des Programms die Session zu recyceln, da diese alle abhängigen Objekte mitrecycelt.
Recyceln im Programm kann sinnvoll sein, aber auch sehr gefährlich nämlich dann wenn man Objekte die man noch verwenden will recycelt hat.
Ist mir selber schon passiert in grossen Programmen, das ich auf ein Objekt mehrere Referenzen hat. Dann habe ich bei einer Referenz weil ich ja ein braver Recycler bin recycle aufgerufen und wie ich dann über eine andere Referenz auf das Objekt zugreifen wollte. Bumm
Grüße
Ralf
flaite:
Wieso Grundsatzdiskussion?
In Java braucht man sich nur dahingehend darum kümmern, dass man nicht zu viele Objekte erzeugt und einen gewissen Überblick behält, wie die Referenzen gesetzt sind. Ein Objekt wird garbage collected, wenn es null ist und kein anderes Objekt mehr eine Referenz auf es hält (wenn ich mich recht erinnere).
Bei Notes-Objekten ist das ein bischen anders. Man braucht diese recycle()-Methode.
Speicherallokation ist im Grunde ein Scope/Lebenszyklus-Problem.
Objekte haben im Programm meist sehr unterschiedliche Lebenszyklen.
Schleifen besitzen nun einen klar definierten engen scope der mehrmals durchlaufen wird.
Objekte, die im scope des Schleifenkörpers erzeugt wurden, haben einen Lebenszyklus von genau einer Iteration dieser Schleife.
In
--- Code: ---for (int i=0; i < 10; i++) {
Document doc = vw.getNthDocument(i)
}
--- Ende Code ---
werden über die eine Zeile in der Schleife eine Menge lokaler Objekte erzeugt, die nur für genau eine Iteration der Schleife im aktiven scope sind und danach nicht mehr gebraucht werden. Man kann sie auch nicht referenzieren. Sie sind lebenszyklustechnisch eindeutig auf dem Weg in den Himmel (katholisch gesprochen).
Zwar verweist immer die gleiche Referenzvariable auf besagte Objekte. Die Objekte sind aber unterschiedlich!!!
In Java ist das ein geringeres Problem, da sie automatisch garbage-collected werden. Notes-Java-Objekte benötigen aber den Aufruf von recycle(), um wirklich garbage collected werden zu können (vereinfacht gesprochen).
Wegen dem schnellen scope-Wechsel in Schleifen, macht der häufige Aufruf von recycle() sehr viel Sinn und das ist in keinster Weise eine irgendwie unscharfe Idee.
So ungefähr jedenfalls.
Thomator:
@Ralf
ich bin da wohl in meinem Denken ein bisschen versaut,weil ich in Java-Agenten meist mit eigenen DIIOP-Sessions arbeite (Remote-Zugriffe in 5'er Server-Landschaften), bin ich gezwungen, alle Objekte selber zu recyclen. Auch bei der Arbeit mit der API aus anderen Java-Applikationen ist es meines Wissens nach nötig, alle Objekte zu recyclen, da das Recyclen der Session alleine nur die Session, nicht die daraus erworbenen Objekte betrifft.
@Axel
Die Java-Objekte an sich werden ja schon von der Garbage-Collection zerstört, oder? Nur die C-Objekte für die nativen Zugriffe benötigen das Recyclen, da ja C-Objekte immer explizit zerstört werden müssen.
Das ist übrigens eine Frage, die mich schon länger beschäftigt: Hätte man die API nicht grundsätzlich so aufbauen können, dass in der finalize-Methode des Objekts das Recyclen mit durchgeführt wird? Dann würde die Garbage-Collection auch die Speicherbereinigung übernehmen.
Thomas
Ralf_M_Petter:
@Thomas!
Nein Recyceln der Session reicht. Es gab mal in frühren 5er ein paar Ausnahmen, aber nichts tragisches auf Grund von Bugs. Aber in 6er funktioniert das recyceln von Session einwandfrei. Unsere gesamte Webseite ist auf diesen Mechanismus aufgebaut und selbst bei tausenden Zugriffen am Tag wo die Session und viele abhängige Objekte tausende mal erstellt und über die Session recycelt wurden treten keine Memory leaks auf.
Bezüglich des GC hast du Recht nur leider kann man das finalize nicht verwenden, da finalize vom GC Thread aufgerufen wird und das recycle in dem Thread gemacht werden soll in dem die Session erstellt wurde. Ich mach prinzipiell in jedem Thread eine eigene Session.
Grüße
Ralf
flaite:
--- Zitat von: Thomator am 01.02.06 - 16:45:59 ---
@Axel
Die Java-Objekte an sich werden ja schon von der Garbage-Collection zerstört, oder? Nur die C-Objekte für die nativen Zugriffe benötigen das Recyclen, da ja C-Objekte immer explizit zerstört werden müssen.
--- Ende Zitat ---
Ralfs Erklärung mit den Threads kannte ich noch gar nicht. Das hört sich irgendwie schlüssig an.
Ich sah das bisher so (und ich bin mir nicht 100% sicher, ob das stimmt): In einem Garbage Collection Lauf werden gar nicht alle Objekte-eligible-for-garbage-collection garbage collected. Kleinere Objekte bleiben liegen. Das hat Optimierungsgründe. Aus Sicht des GC sind aber die Notes Wrapper um die C-Objekte kleine Objekte (obwohl sie massiv C-Zeugs binden, aber das sieht der GC nicht).
Das Problem ist, dass sie zulange liegen bleiben.
Und beim stoppen der VM wird nicht unbedingt auf allen Objekten finalize() aufgerufen. Auch übrigens dann nicht, wenn im finalize() vorher eine Exception geworfen wurde.
Man sollte sich nicht auf finalize() verlassen, es sei denn, man weiss wirklich was man tut. Ich habe die finalize() Methode noch nie benutzt (ausser für kleinere Tests).
Wie das meiste in diesem Theater, ist garbage-collection nicht so einfach wie es zunächst aussieht.
Gruß Axel
Navigation
[0] Themen-Index
[#] Nächste Seite
[*] Vorherige Sete
Zur normalen Ansicht wechseln