About Duffbert...

Duffbert's Random Musings is a blog where I talk about whatever happens to be running through my head at any given moment... I'm Thomas Duff, and you can find out more about me here...

Email Me!

Search This Site!

Custom Search

I'm published!

Co-author of the book IBM Lotus Sametime 8 Essentials: A User's Guide
SametimeBookCoverImage.jpg

Purchase on Amazon

Co-author of the book IBM Sametime 8.5.2 Administration Guide
SametimeAdminBookCoverImage.jpg

Purchase on Amazon

MiscLinks

Visitor Count...



View My Stats

« From the KB - How to Use LotusScript to Force Users to Use an Edit Button Rather than Edit Menu Command | Main| IBM dumping Windows as an internal standard? »

Be kind to your Domino server when using Java... recycle()

Category Software Development

Joe Litton and I are preparing a session for next month's meeting of the Portland Domino-Notes User Group that will cover Java For The Domino Developer.  The focus will be taking what you already know about LotusScript and relating it to writing Domino agents in Java.  Think of it as a short-cut method to getting started with learning Java...

One of the items we'll cover is the use of the "recycle()" method of each Domino object when coding in Java.  This is a critical item that Joe learned all too well when he was working on a project for a former employer.  As in crashing the mail server each night until he learned about this feature...  :-)

From the KnowledgeBase...

Why it is Important to Use Recycle() Method on Every Java Object That is Created

Document Number:  1097861

Problem
You want to use Java in either an agent, a servlet, an applet or a stand-alone application to access Notes Objects.  This can be used to access information locally on the same server or remotely on a different server, in which case CORBA (Common Object Request Broker Architecture) would be used.  All of the above have been created to mimic the LotusScript Object Model and make it easier for developers to use these tools.  For example, to get a handle on a database using LotusScript, the session contains the current database.  This is also true for the Java classes.  Once you create a session, you may reference a database through the session.  When does a developer need to invoke the method recycle() for this code?

Content
When you create an object in LotusScript, you create two objects - one in LotusScript and one in the Notes back-end (C++ code). The LotusScript object "points" to the C++ object, which really implements the class's behaviors.  When the LotusScript agent or event ends, both objects are destroyed automatically.  If the objects were not, they would stay resident in memory thereby creating a memory leak.

If you create an object in Java, the same applies - it's a pointer that points to an object that is created in C++.  It is common in pure Java coding to set something to null in order for it to be flagged for garbage collection (gc) immediately, and this is called "aggressive" garbage collection.  However, when using the Notes Objects for Java, setting something to null marks the Java object for garbage collection, but does not mark the C++ object for garbage collection.  De-referencing the Java Object flags it for garbage collection, but nothing will be affected on the C++ Object.  Recycle() destroys the C++ object and sets the Java object for garbage collection.  If you mark things null, you could still experience memory issues.  When using objects in an Agent all objects (both Java and C++) are destroyed when the agent ends.  When using servlets, JSPs or standalone applications recycle must be used as Domino will never clean up these backend objects

Conversely, if an object has been set to be recycled, it will not be marked null.  You could, in theory, reference the object again - it shouldn't crash, it would merely throw an exception.  This is important when there are multiple references to the same object; "db = mydb.nsf" as well as, later on "db = yourdb.nsf".  Redefining your reference in this manner is not recommended.  It can be confusing and can therefore yield unreliable results.

In a perfect world, the developer needs to be sufficiently familiar with the application to understand what objects are created, what they are set to and when they are used.  However, developers often inherit code to manage with which they are not familiar.  One thing that's important to know is that the objects form a hierarchy.  That is, recycling a parent - such as a document - will recycle it's children - such as an item.  Since the session object is at the top of the hierarchy, recycling the session will recycle everything that has been used from it.

One thing that you can do is go to the design pane in Domino Designer and click in the code area and do a Find on "recycle" or whatever object for which you may be searching.   Set the scope of the Find for current or all objects.  If you do a search for recycle()s and don't find any, then the first thing that should be done is to remedy the situation by having the developer go through and add this bit of code to all objects after they are finished being used.  One thing to watch out for is the use of New being instantiated in a loop.  For every iteration of the loop and new object is created.  Unless you recycle() the object within the loop this object will stay resident in memory.

Here's an example of using recycle() within a loop as well as using aggressive garbage collection:

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 re-save

// 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();
   }
 }
}

Comments

Gravatar Image1 - Oi, yes, that's a pain. There's obviously a good reason, but I've wondered why the Java destructor can't just call close() on the API object?

Post A Comment

:-D:-o:-p:-x:-(:-):-\:angry::cool::cry::emb::grin::huh::laugh::lips::rolleyes:;-)

Want to support this blog or just say thanks?

When you shop Amazon, start your shopping experience here.

When you do that, all your purchases during that session earn me an affiliate commission via the Amazon Affiliate program. You don't have to buy the book I linked you to (although I wouldn't complain!). Simply use that as your starting point.

Thanks!

Thomas "Duffbert" Duff

Ads of Relevance...