When you start coding Java in Domino you will eventually face problems related to memory leaks - at least if you are using version 7 and below and especially if you are using large loops in your code. I am saying version 7 and below because I don't yet know if it is working differently for version 8 or 8.5 since it's built on the eclipse form, which means Java and not C++.
For version 7 and below the Notes backend consists of C++ code. This means that, when you create objects in agents or servlets, two objects are created for each one you create - disregarding if you are coding in LotusScript or Java. For LotusScript both of these objects are destroyed automatically when an agent or event ends. For Java this is unfortunately not true which could lead to memory leaks and unexpected problems if you're not aware of this.
Java have a so-called Garbage Collector (gc) which takes care of objects that has no reference pointing to them, i.e. objects that previously had a reference but where the reference now has been nulled. The purpose of this is to make sure there is always enough memory. Otherwise the memory would quickly be full of objects, which in turn would lead to the machine breaking down since the processor would not have any memory left to process any other work. This is usually not a problem in pure Java though since when a program ends its objects will become eligible for garbage collection. It could be a problem in loops though or in large environments with many programs running. So if you want an object to become eligible for garbage collection you can set the reference to it (the one you're working with) to null to speed up the process.
When it comes to Java in Domino it is sligthly different. You don't only have to worry about nulling objects for the Java purpose but you also have to worry about the C++ objects
for the Domino Java objects you create in your agent or servlet. That is why there is a method called 'recycle' created that can be called for any Domino Java object. This call will destroy the C++ object and set the corresponding Java object for garbage collection.
It is recommended to use this in loops but otherwise you should not have to deal with either - although it can't be a bad thing. A real-life example that I have had was an archive agent that was suppose to run once a year. The view holding the documents that was to be archived had 80000 documents. It had no recycle functionality in it and failed its task - most likely because of this. This guess was verified since it worked when I changed the loop to use recycle (the same way as the code below).
Here is an example code from IBM:
import lotus.domino.*; public class JavaAgent extends AgentBase { public void NotesMain() {
try { Session session = getSession(); AgentContext agentContext = session.getAgentContext(); Database db = agentContext.getCurrentDatabase(); View v = db.getView("SomeView");
// turn off auto-update so that if we make a change to a document // and resave, it won't affect the sort order in the view v.setAutoUpdate(false);
Document doc = v.getFirstDocument(); Document temp = null; //sets the temp for garbage collection immediately
while (doc != null) { // do something with the document here... // whatever, just don't delete it (yet)! temp = v.getNextDocument(doc); // get the next one doc.recycle(); // recycle the one we're done with doc = temp; } // end while
} catch(Exception e) { e.printStackTrace(); } }
} |
Also worth noting is that recycling one object also recycles all of its children.
There is a on IBM developerWorks on this issue with more information.