Autor Thema: Recyclen von Notesobjekten unter Java so korrekt ?  (Gelesen 2897 mal)

Offline ghostmw

  • Aktives Mitglied
  • ***
  • Beiträge: 201
  • Geschlecht: Männlich
    • BELOS - Raum+Ressourcenmanagement unter Lotus Notes
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();
			}
		}
	}

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 ?
« Letzte Änderung: 18.02.13 - 10:50:26 von ghostmw »
Grüße
Marco Weller
Lotus Domino / Lotus Notes seit 1996 (ab 4.5x)

Offline Ralf_M_Petter

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.879
  • Geschlecht: Männlich
  • Jeder ist seines eigenen Glückes Schmied
    • Ralf's Blog
Re: Recyclen von Notesobjekten unter Java so korrekt ?
« Antwort #1 am: 20.02.13 - 12:52:47 »
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
Jede Menge Tipps und Tricks zu IT Themen findet Ihr auf meinem Blog  Everything about IT  Eine wahre Schatzkiste sind aber sicher die Beiträge zu meinem Lieblingsthema Tipps und Tricks zu IBM Notes/Domino Schaut doch einfach mal rein.

Offline Ralf_M_Petter

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.879
  • Geschlecht: Männlich
  • Jeder ist seines eigenen Glückes Schmied
    • Ralf's Blog
Re: Recyclen von Notesobjekten unter Java so korrekt ?
« Antwort #2 am: 20.02.13 - 12:58:07 »
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
Jede Menge Tipps und Tricks zu IT Themen findet Ihr auf meinem Blog  Everything about IT  Eine wahre Schatzkiste sind aber sicher die Beiträge zu meinem Lieblingsthema Tipps und Tricks zu IBM Notes/Domino Schaut doch einfach mal rein.

Offline ghostmw

  • Aktives Mitglied
  • ***
  • Beiträge: 201
  • Geschlecht: Männlich
    • BELOS - Raum+Ressourcenmanagement unter Lotus Notes
Re: Recyclen von Notesobjekten unter Java so korrekt ?
« Antwort #3 am: 20.02.13 - 13:52:10 »
Ok, ich bastel das ganze mal zusammen und poste das ganze als Anhang.
Grüße
Marco Weller
Lotus Domino / Lotus Notes seit 1996 (ab 4.5x)

Offline ghostmw

  • Aktives Mitglied
  • ***
  • Beiträge: 201
  • Geschlecht: Männlich
    • BELOS - Raum+Ressourcenmanagement unter Lotus Notes
Re: Recyclen von Notesobjekten unter Java so korrekt ?
« Antwort #4 am: 20.02.13 - 15:23:37 »
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.

Grüße
Marco Weller
Lotus Domino / Lotus Notes seit 1996 (ab 4.5x)

Offline Ralf_M_Petter

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.879
  • Geschlecht: Männlich
  • Jeder ist seines eigenen Glückes Schmied
    • Ralf's Blog
Re: Recyclen von Notesobjekten unter Java so korrekt ?
« Antwort #5 am: 20.02.13 - 15:30:26 »
Kannst du mal meine Empfehlungen umsetzen. Erstens Errorhandling beim Session recyceln und die sinnlosen recycle vorm recyceln der Session rausnehmen. Dann nochmal testen, ob eine Exception vor dem Recyceln der Session geworfen wird.

Ich schau mir deinen Code gerade durch ob mir etwas auffällt.
Jede Menge Tipps und Tricks zu IT Themen findet Ihr auf meinem Blog  Everything about IT  Eine wahre Schatzkiste sind aber sicher die Beiträge zu meinem Lieblingsthema Tipps und Tricks zu IBM Notes/Domino Schaut doch einfach mal rein.

Offline ghostmw

  • Aktives Mitglied
  • ***
  • Beiträge: 201
  • Geschlecht: Männlich
    • BELOS - Raum+Ressourcenmanagement unter Lotus Notes
Re: Recyclen von Notesobjekten unter Java so korrekt ?
« Antwort #6 am: 20.02.13 - 15:32:21 »
OK ... bis gleich.
Grüße
Marco Weller
Lotus Domino / Lotus Notes seit 1996 (ab 4.5x)

Offline Ralf_M_Petter

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.879
  • Geschlecht: Männlich
  • Jeder ist seines eigenen Glückes Schmied
    • Ralf's Blog
Re: Recyclen von Notesobjekten unter Java so korrekt ?
« Antwort #7 am: 20.02.13 - 15:50:02 »
Hier noch ein paar Empfehlungen:

Die CheckNotices Methode kann radikal verschlankt werden. Schmeiss alles was Viewentrys betrifft raus.

Um über alle Dokumente zu iterieren hat sich folgende Methode als am einfachsten herausgestellt.


Code
Document doc=view.getFirstDocument();
while(doc!=null){
  //Mach irgendwas mit dem doc.
  Document tempdoc=doc;
  doc=view.getNextDcoument(doc);
  tempdoc.recycle();
}


Danach brauchst du kein recycle mehr. Da beim letzten Durchlauf doc null ist und nicht recycelt werden muss.

Das selbe gilt, wenn du über eine ViewEntryCollection gehst. Deine Vorgehendsweise erscheint mir etwas umständlich.

Jede Menge Tipps und Tricks zu IT Themen findet Ihr auf meinem Blog  Everything about IT  Eine wahre Schatzkiste sind aber sicher die Beiträge zu meinem Lieblingsthema Tipps und Tricks zu IBM Notes/Domino Schaut doch einfach mal rein.

Offline Ralf_M_Petter

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.879
  • Geschlecht: Männlich
  • Jeder ist seines eigenen Glückes Schmied
    • Ralf's Blog
Jede Menge Tipps und Tricks zu IT Themen findet Ihr auf meinem Blog  Everything about IT  Eine wahre Schatzkiste sind aber sicher die Beiträge zu meinem Lieblingsthema Tipps und Tricks zu IBM Notes/Domino Schaut doch einfach mal rein.

Offline ghostmw

  • Aktives Mitglied
  • ***
  • Beiträge: 201
  • Geschlecht: Männlich
    • BELOS - Raum+Ressourcenmanagement unter Lotus Notes
Re: Recyclen von Notesobjekten unter Java so korrekt ?
« Antwort #9 am: 20.02.13 - 17:20:13 »
Danke für die Tipps ...

ich muss das alles erstmal umsetzen und testen.
Grüße
Marco Weller
Lotus Domino / Lotus Notes seit 1996 (ab 4.5x)

Offline Ralf_M_Petter

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.879
  • Geschlecht: Männlich
  • Jeder ist seines eigenen Glückes Schmied
    • Ralf's Blog
Re: Recyclen von Notesobjekten unter Java so korrekt ?
« Antwort #10 am: 21.02.13 - 17:08:45 »
Hat es geklappt?
Jede Menge Tipps und Tricks zu IT Themen findet Ihr auf meinem Blog  Everything about IT  Eine wahre Schatzkiste sind aber sicher die Beiträge zu meinem Lieblingsthema Tipps und Tricks zu IBM Notes/Domino Schaut doch einfach mal rein.

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz