IBM Support

Why it is important to use the Recycle() method on every Java object

Technote (FAQ)


Question

You want to use Java in either an agent, a servlet, an applet, or a standalone application to access Lotus Notes'® objects for information locally on the same server.

The above applets mimic the LotusScript object model to make it easier for developers to use these tools. For example, to get a handle on a database using LotusScript or Java classes, the session contains the current database. Once you create a session, you can reference a database through the session.

It is very important to recycle every object that is created for maximum system performance. When is it best to invoke the Recycle() method for this and other Java objects?


Answer

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

Creating an object in Java:
If you create an object in Java, the same applies. This object is 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. This is called "aggressive" garbage collection.

However, when using 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. Dereferencing the Java object flags it for garbage collection but nothing will be affected on the C++ object.

Why recycle?
Recycle() destroys the C++ object and sets the Java object for garbage collection. If you mark objects Null, you can still experience memory issues. When using objects in an agent, all objects (both Java and C++) are destroyed when the agent ends. For this reason, in an agent context, recycling single use objects such as the Session and View objects is not as important as in other contexts. However, object variables that are used over and over, such as those pointing to Document objects, definitely need to be recycled to avoid memory depletion during the agent run, even though those objects will be cleaned up at agent termination. Also, when using servlets, .jsp's, or standalone applications, recycle must be used since Domino will never clean up these backend objects.

Conversely, if an object is set to be recycled, it will not be marked Null. In theory, you could reference the object again and it wouldn't crash, just merely throw an exception. This is important when there are multiple references to the same object; "db = mydb.nsf" as well as, "db = yourdb.nsf". Redefining your reference in this way is not recommended since it can be confusing and yield unreliable results.

It is important to understand what objects are created, what they are set to, and when they are used. Objects form a hierarchy. For example, recycling a parent document also recycles its children. Since the session object is at the top of the hierarchy, recycling the session will recycle everything that is used from it.

Finding objects:
Go to the Design pane in Domino Designer, click in the code area, and do a Find on "recycle" or the object for which you are 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, you can remedy the situation by having a developer go through and add the code below 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, a new object is created. Unless you recycle the object within the loop, this object will stay resident in memory.

NOTE: The code below is a sample script, provided to illustrate one way to approach this issue. It is to be used as is and at your own risk. In order for this example to perform as intended, the script must be laid out exactly as indicated below. Product Support cannot customize this script for specific environments or applications.

Example of using Recycle() within a loop and 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 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();
        }
      }
    }

Related information

A simplified Chinese translation is available

Historical Number

186643

Document information

More support for: IBM Notes
Performance

Software version: 8.5, 9.0

Operating system(s): Linux, Windows

Software edition: All Editions

Reference #: 1097861

Modified date: 24 August 2007


Translate this page: