Domino 9 und frühere Versionen > ND8: Entwicklung

Recyclen von Notesobjekten unter Java so korrekt ?

(1/3) > >>

ghostmw:
Moin zusammen,

ich habe folgenden Code in einem Java Server-Addin-Task platziert und habe "meiner Meinung" nach alle Notesobjekte nach Verwendung sauber recycelt. Der Dominoserver ist 8.5.3 auf WIndows 7 / 64Bit.

Der Speicher läuft mir bis auf 500 MB hoch, und wird nicht freigegeben, bei jedem Lauf mit 10000 neuen Dokumenten zum Verarbeiten um weitere 100 MB hoch.

Die Routine(n) anbei, ist da noch irgendwas "faul" ?
Aufgerufen wird immer die Funktion CheckAll


--- Code: ---private void checkAll() {
Session session = null;
Database dbCurrent = null;
View viwDocs= null;
View viwLookUp = null;
ViewEntryCollection vecDocs = null;
ViewEntry veEntry = null;
ViewEntry veNext = null;
Document doc2Use = null;


try
{
session = NotesFactory.createSession();
dbCurrent = session.getDatabase(null, DATABASE);

viwDocs= dbCurrent.getView(VIEW);
if (viwDocs== null) {
...
} else {
viwDocs.refresh();
viwDocs.setAutoUpdate(false);

viwLookUp = dbCurrent.getView(VIEW);
if (viwLookUp == null) {
...
} else {
viwLookUp.setAutoUpdate(false);

vecDocs = viwDocs.getAllEntries();

veEntry = vecDocs.getFirstEntry();
if (veEntry == null ) {
...
}

while ( veEntry != null ) {
veNext = vecDocs.getNextEntry(veEntry);

if (veEntry.isDocument()) {
doc2Use = veEntry.getDocument();

if (this.isOK(doc2Use, dbCurrent, viwLookUp)) {
this.doSomething(doc2Use, dbCurrent);
} else {
doc2Use.replaceItemValue("MyField", "VALUE");
doc2Use.save(true,false);
}
doc2Use.recycle();
}
veEntry.recycle();
veEntry = veNext;
}
}
}
}
}  catch (NotesException ne)  {
...
}  catch (Exception e)  {
...
}

finally {

// keep the memory clean
try
{
if (vecDocs != null) vecDocs.recycle();
if (veEntry != null) veEntry.recycle();
if (veNext != null) veNext.recycle();
if (viwDocs!= null) viwNotices.recycle();
if (viwLookUp != null) viwLookUp.recycle();
if (dbCurrent != null) dbCurrent.recycle();
session.recycle();

}  catch (Exception e)  { }

System.gc();
}
}

private boolean isOK ( Document doc2Check, Database db, View viwLookUp ) {
ViewEntryCollection vecEntries = null;
ViewEntry veCurrent = null;
ViewEntry veNext = null;
DateTime start = null;
DateTime end = null;
DateTime end_ = null;
DateTime start_ = null;
Vector tmpValues = null;

try {
viwLookUp.refresh();
viwLookUp.setAutoUpdate(false);

String strKey = "xxx";
vecEntries = viwLookUp.getAllEntriesByKey(strKey, true);

start = doc2Check.getFirstItem("ABC").getDateTimeValue();
end = doc2Check.getFirstItem("DEF").getDateTimeValue();

veCurrent = vecEntries.getFirstEntry();

while ( veCurrent != null ) {
veNext = vecEntries.getNextEntry(veCurrent);
tmpValues = veCurrent.getColumnValues();

start_ = (DateTime) tmpValues.elementAt(1);
end_ =  (DateTime) tmpValues.elementAt(2);

boolean boExit = !( end_.timeDifference(start) < 0 || start_.timeDifference(end) > 0);

start_.recycle();
end_.recycle();

if ( boExit ) return false;

veCurrent.recycle();
veCurrent = veNext;
}

return true;
} catch (NotesException ne) {

String line = " in line " + ne.getStackTrace()[2].getLineNumber();
consolePrint(progName + " - Notes Error checking free time: " + ne.id + " " + ne.text  + line);
return false;
}  catch (Exception e)  {
String line = " in line " + e.getStackTrace()[2].getLineNumber();
consolePrint(progName + " - Java Error checking free time: " + e.getMessage() + line);
return false;
}

finally{
try {
if ( start != null ) start.recycle();
if ( end != null ) end.recycle();
if ( start_ != null ) start_.recycle();
if ( end_ != null ) end_.recycle();
if ( veCurrent != null ) veCurrent.recycle();
if ( veNext != null ) veNext.recycle();
if ( vecEntries != null ) vecEntries.recycle();

} catch (NotesException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}

private void doSomething ( Document doc2Check, Database dbCurrent ) {
Document docNew = null ;
View viwLookUp= null;
try {
viwLookUp = dbCurrent.getView(VIEW);
String strKey = "YYY";

viwLookUp .refresh();
viwLookUp .setAutoUpdate(false);

docNew = viwLookUp .getDocumentByKey(strKey, true);

docNew = docNew == null ? dbCurrent.createDocument() : docNew;

docNew.replaceItemValue("Form","XXX");

...

docNew.save(true, false);

doc2Check.replaceItemValue("YYY", "***");
doc2Check.save(true,false);


} catch (NotesException ne) {
...
}  catch (Exception e)  {
...
}

finally {
try {
if ( docNew != null ) docNew.recycle();
if ( viwLookUp!= null ) viwLookUpApptUNID.recycle();
} catch (NotesException ne) {
ne.printStackTrace();
}
}
}

--- Ende Code ---

Ich für meinen Teil würde sagen, ich habe alles sauber recyclet, so wie es Lotus / IBM für Schleifen vorgibt oder ?
Hat jemand noch eine Idee ?

Ralf_M_Petter:
Ich würde auf jeden Fall mal in dem catch des Try Blocks wo du die Session recyceltst ein e.printStackTrace() einfügen. Falls eines der vorhergehenden Recycles eine Exception wirft, bekommst du es nicht mit.  Übrigens kannst du dir die ganzen recycles vor dem session.recycle() sparen. Das System.gc() würde ich auch gleich mal wieder entfernen, da man das auf keinen Fall in Produktivcode verwenden sollte.

Grüße

Ralf

Ralf_M_Petter:
Ausserdem würde ich an deiner Stelle ein echtes Beispiel, dass den Fehler hat posten. Dein Code ist nämlich nicht lauffähig und wie soll man an einem nicht lauffähigen Code sagen, wo der Fehler ist.

Grüße

Ralf

ghostmw:
Ok, ich bastel das ganze mal zusammen und poste das ganze als Anhang.

ghostmw:
So anbei die Test-Datenbank, dort läuft ein periodischer Agent, der die Dokumente verarbeitet und den Speicher zu ballert.
Er beinhaltet den Code (s.o.) und läuft alle 5 min.

Nach 3x Laufen ist der Amgr-Task bereits bei 1-2 GB RAM ... (von 8 GB max. auf der Maschine).

Und das ganze für 1000 neue Dokumente.

Navigation

[0] Themen-Index

[#] Nächste Seite

Zur normalen Ansicht wechseln