Ich hab des öfteren Probleme mit der Speicherbelastung durch einen Java-Agent, der mit LotusNotes-Objekten arbeitet. Ich hab mir diverse Beiträge zum Recyclen von NotesObjekten durchgelesen und meines Erachtens diese auch in meinem Agenten umgesetzt, trotzdem habe ich im Vergleich zu der LotusScript Variante einen eklatant hörenen Speicherverbrauch (der auch nicht mehr freigegeben wird).
Ich verwende im Agenten einen eigenen Datentyp, der String-Objekte und ein Datums-Objekt aufnimmt.
Kann mir jemand sagen, ob ich das Recyclen richtig mache oder wo NotesObjekte die Referenz verlieren und weiterhin im Heap bestehen bleiben?
mport java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import datentyp.LogEntry;
import lotus.domino.*;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
//Globale Variablen
Session session = getSession();
Database db = session.getDatabase(session.getServerName(), "domlog.nsf");
Database dbCurrent = session.getCurrentDatabase();
View viewEinstellungen = dbCurrent.getView("(Einstellungen)");
Document docZusammenfassung, docProfilDokument, docTmp, docDomLog;
LogEntry logEntryTmp = new LogEntry();
HashMap<String, LogEntry> listLogEntries = new HashMap<String,LogEntry>(100000);
List<String> listDelete = new ArrayList<String>();
Name nameUsername = null;
DateTime dtErstesDoc, dtLogEntry, dtStichtag;
String strRequest, strTranslatedURI;
int intStatus, intZaehlerTageStay = 14, intZaehlerTageEdit = 1, intDifferenz;
//Profildokument auslesen (Anzahl der Tage die stehengelassen werden sollen
docProfilDokument = viewEinstellungen.getDocumentByKey("ProfileDocument");
if(docProfilDokument != null)
{
intZaehlerTageStay = docProfilDokument.getItemValueInteger("AnzahlTageStayNO");
intZaehlerTageEdit = docProfilDokument.getItemValueInteger("AnzahlTageEditNO");
}
docProfilDokument.recycle();
viewEinstellungen.recycle();
dtStichtag = session.createDateTime("01.01.2000");
dtStichtag.setNow();
dtStichtag.adjustDay(-intZaehlerTageStay);
for(int j=0; j<intZaehlerTageEdit; j++)
{
//Collection aus allen Dokumenten in der domlog.nsf bilden
DocumentCollection collDoc = db.getAllDocuments();
docDomLog = collDoc.getFirstDocument();
if(docDomLog == null)
{
break;
}
dtErstesDoc = docDomLog.getCreated();
dtLogEntry = docDomLog.getCreated();
intDifferenz = dtStichtag.timeDifference(dtErstesDoc)/86400;
//Solange Dokumente von einem Tag vorhanden sind und diese nicht aufgrund der Eingabe aus dem
//Profildokument stehengelassen werden sollen
while(docDomLog != null && dtLogEntry.getDateOnly().equals(dtErstesDoc.getDateOnly()) && intDifferenz>= 0)
{
/**
*Hier kommt weiterer Code, der jedoch keine LotusNotes Objekte verwendet
*/
//Erstes Dokument
if(listLogEntries.size() == 0)
{
LogEntry logEntry = new LogEntry(strSearchString, 1, dblContentLength,strUsername, strUseradresse, strZugriff,
strTranslatedURI, strServer, intStatus, dtLogEntry);
listLogEntries.put(strSearchString, logEntry);
}
//für jedes weitere Dokument
else
{
logEntryTmp = listLogEntries.get(strSearchString);
if(logEntryTmp != null)
{
//Es besteht bereits ein passender Eintrag
logEntryTmp.setIntAnzahlZugriffe(logEntryTmp.getIntAnzahlZugriffe()+1);
logEntryTmp.setDblContentLength(logEntryTmp.getDblContentLength()+ dblContentLength);
listLogEntries.put(strSearchString, logEntryTmp );
}
else
{
//Es besteht noch kein passender Eintrag
LogEntry newLogEntry = new LogEntry(strSearchString, 1, dblContentLength,strUsername, strUseradresse, strZugriff,
strTranslatedURI, strServer, intStatus, dtLogEntry);
listLogEntries.put(strSearchString,newLogEntry);
}
}
//dtLogEntry.recycle();
docTmp = collDoc.getNextDocument(docDomLog);
if(docTmp != null)
{
//dtLogEntry.recycle();
dtLogEntry =docTmp.getCreated();
}
listDelete.add(docDomLog.getUniversalID());
docDomLog.recycle();
docDomLog = docTmp;
}//Ende while-Schleife
//Schreiben der Dokumente
//######################################################################################################
for(Object value : listLogEntries.values())
{
logEntryTmp = (LogEntry) value;
docZusammenfassung = dbCurrent.createDocument();
docZusammenfassung.replaceItemValue("Form", "Datenbankzugriff");
DateTime datum = session.createDateTime(logEntryTmp.getDatum().getDateOnly());
docZusammenfassung.replaceItemValue("DatumDT", datum);
docZusammenfassung.replaceItemValue("UsernameTX", logEntryTmp.getStrUsername());
docZusammenfassung.replaceItemValue("UseradresseTX", logEntryTmp.getStrUseradresse());
docZusammenfassung.replaceItemValue("ServerTX", logEntryTmp.getStrServer());
docZusammenfassung.replaceItemValue("ZugriffTX", logEntryTmp.getStrZugriff());
docZusammenfassung.replaceItemValue("StatusNO", logEntryTmp.getIntStatus());
docZusammenfassung.replaceItemValue("TranslatedURITX", logEntryTmp.getStrTranslatedURI());
docZusammenfassung.replaceItemValue("AnzahlZugriffeNO", logEntryTmp.getIntAnzahlZugriffe());
docZusammenfassung.replaceItemValue("ContentLengthNO", logEntryTmp.getDblContentLength());
docZusammenfassung.save(true,true);
docZusammenfassung.recycle();
datum.recycle();
logEntryTmp.datum.recycle();
}
//#####################################################################################################
listLogEntries.clear();
dtErstesDoc.recycle();
for(int i=0; i<listDelete.size(); i++)
{
docTmp = db.getDocumentByUNID(listDelete.get(i));
docTmp.removePermanently(true);
docTmp.recycle();
}
} //Ende erste for-Schleife
//Recycle NotesObjekte
dtStichtag.recycle();
db.recycle();
dbCurrent.recycle();
session.recycle();
} catch(Exception e) {
e.printStackTrace();
}
}