Lotus Notes / Domino Sonstiges > Java und .NET mit Notes/Domino

Error cleaning up agent threads und WeakReference...

<< < (4/19) > >>

Mark³:
Zwischenstand:
Als Workaround (ITIL lebe hoch) habe ich erstmal die großen jars (Web-api für Openview und Openlog-Funktionen) in eine Java-Lib in der Datenbank gepackt und die Agenten von Imported Java auf Java umgestellt.
Nachteil: Ich entwickle weiterhin in Eclipse, muss den Sourcecode aber in den Notesagenten reinpasten anstatt nur Refresh zu drücken
Vorteil: Bei einem ersten Test schint der Fehler nicjht mehr aufzutreten. Habe in der Debug-Konsole mal mit m einen Memorydump gemacht nach jeweils einer Transaktion. Ergebnis:

1. 84% free
2. 34% free
3. 34% free aber 70k weniger als bei letztem Schritt
4. 34% free aber 70k weniger als bei letztem Schritt
5. 34% free aber 70k weniger als bei letztem Schritt
6. 80% free

Anscheinend läuft der Garbage Collector und erlöst den Client dann vom Speichermüll. Leider bekomme ich aber immer noch 'Error cleaning up agent...' daher möchte ich langfristig auf jeden Fall die Openview-Zugriffe separat in einer vernünftigen VM laufen lassen.
Im Agenten rufe ich zwar auch ein System.gc() am Ende auf, aber das scheint nicht direkt was zu tun sondern eher ein Tip für die VM zu sein, die Garbage Collection eher früher als geplant laufen zu lassen.

Mark³:
hier noch mal ein paar Details zu meinem Recycling, vielleicht ist hier ja auch ein Wurm drin:


--- Code: ---public void NotesMain() {
oli = new OpenLogItem();
try {
session = getSession();
AgentContext agentContext = session.getAgentContext();
DocumentCollection dc = agentContext.getUnprocessedDocuments();
Agent agent = agentContext.getCurrentAgent();
db = agentContext.getCurrentDatabase();
profileDoc = db.getProfileDocument("abc", "");

ov = new OVTool();
if (ov != null) {
...
Document doc = dc.getFirstDocument();
while (doc != null) {

doc = dc.getNextDocument();
}
ov.disconnect();
ov = null;
}

profileDoc.recycle();
db.recycle();
agent.recycle();
agentContext.recycle();
session.recycle();
}

catch (Exception e) {
oli.logError(e);
System.gc();
}
oli.recycle();
System.gc();
}
--- Ende Code ---

Und noch ov.disconnect() im Detail:


--- Code: ---public void disconnect()  {
oli.recycle();
s.closeConnection();  //beendet die Openview Session
s = null;

}
--- Ende Code ---

In meiner Iteration der DocumentCollection könnte ich noch ein tempDoc deklarieren und damit bei jedem Durchlauf das momentane doc recyclen (habe ich bei notes.net als aggressives oder so ähnlich Recycling gesehen aber der Sinn hat sich mir nicht erschlossen da das Recyclen der DocumentCollection doch eigentlich auch alle docs mitnehmen sollte, die dadrin sind, oder? Gleiches müsste dann natürlich auch für die db und die session gelten. Ist also alles nicht 100%ig verstanden von mir...

Ralf_M_Petter:
Das recycle läuft falsch.

Grundregel: Nur Dokumente recyceln, die du selber erstellt hast. Also auf keinen Fall die Session und den AgentContext recyceln.

Für was du das Objekt agent brauchst entzieht sich ebenfalls meiner Kenntnis. Komisch ist auch die Zeile oli.recycle(). Ist da auch ein Notes Objekt?

Übrigens das mit dem Cleaning up agent Threads ist ja eigentlich keine Fehlermeldung im eigentlichen Sinn, sondern nur ein Hinweis, dass Threads gekillt wurden, die dein Code nicht ordnungsgemäß abschgeschlossen hat. Eventuell solltest du mal deinen OpenView Code in einem Debugger laufen lassen und schauen welche Threads da überbleiben und ob die eine Möglichkeit bieten das zu beenden. System.gc muß nicht aufgerufen werden, vor allem nicht in einem Server.

Zum recyceln in der Schleife, das sollte man auf jeden Fall machen. Wenn die Schleife nur ein paar mal durchlaufen wird, hast du sicher noch kein Problem. Wenn die Schleife jedoch 1000te mal durchlaufen wird, dann bekommst du garantiert ein Memory Problem. Also in Schleifen das Doc immer nach Verwendung recyclen.

Die Document Objekte werden erst beim GetNextDocument erstellt. Was aber stimmt, ist das alle Dokumente die noch nicht recycelt waren beim Recyceln der DC mitgenommen werden. Aber bis dahin kann schon OutOfMemory aufgetreten sein.

Grüße

Ralf

Mark³:
es ist immer schön, mal wieder was dazuzulernen  :)
Die Recycling-Geschichte werde ich nochmal aufgreifen.
Zu oli: das ist das OpenLogItem (OpenLog von openntf.org), für mich gehört das schon selbstverständlicherweise in jede Datenbank rein. (Ich hatte es zum Testen mal komplett rausgelassen, hatte aber keinen Einfluss auf den cleaning up-Mist).
Das agent-Objekt nutze ich, um den Namen des Agents ins Log zu schreiben, ist natürlich Blödsinn, weil das Log sowieso den Namen automatisch logged...

Was sagst du dazu?


--- Code: ---public void NotesMain() {
oli = new OpenLogItem();
try {
session = getSession();
AgentContext agentContext = session.getAgentContext();
DocumentCollection dc = agentContext.getUnprocessedDocuments();
db = agentContext.getCurrentDatabase();
profileDoc = db.getProfileDocument("setup", "");
ov = new OVTool();
if (ov != null) {
Document doc = dc.getFirstDocument();
Document temp = null;
while (doc != null) {
...
temp = dc.getNextDocument(doc); // get the next one
doc.recycle(); // recycle the one we're done with
doc = temp;

}
ov.disconnect();
ov = null;
}
profileDoc.recycle();
db = null;
agentContext = null;
session = null;
}

catch (Exception e) {
e.printStackTrace();
oli.logError(e);

}
oli.recycle();

}

--- Ende Code ---

Mark³:
das geänderte Recycling erlöst mich leider nicht vom cleaning up-Krams. Das liegt wohl wirklich daran, dass Notes die Openview-Geschichte nicht richtig entsorgen kann.
Leider tritt auch der Speicherüberlauf immer noch auf. Bei mir läuft das alles aber bei einem Kollegen trat er wieder auf, obwohl ich nun die jars in eine lib gepackt habe (und vor erneutem Testen die cache.ndk gelöscht habe).

Also doch eigenständiges Java-Programm mit RMI oder sowas. Leider weiß ich noch nicht so richtig, wo ich damit starten soll. Mal sehen, ob Axel was mit Notes 7 und RMI rausfindet, ansonsten werde ich wohl erstmal etwas Literaturrecherche betreiben müssen.
Im Prinzip brauche ich ja nur ein Javaprogramm, welches im main() in einer Endlosschleife auf irgendwelche Ports oder Sockets hört und dann für jeden Aufruf einen Thread laufen läßt, welcher eine Openview-Transaktion durchführt und ein paar Daten zurückmeldet, die ich wieder über Socket an den Caller zurückgebe.   O0

Navigation

[0] Themen-Index

[#] Nächste Seite

[*] Vorherige Sete

Zur normalen Ansicht wechseln