
Memory-wise a program running on a computer uses two discrete pieces of memory – the stack and the heap. The stack is a small(er) piece of memory specific to the method being executed. The heap is much larger and may be shared between programs. No need to worry about the implementation details more than this.
When you instantiate an object in Java you are actually allocating two pieces of memory – one on the stack and one on the heap. The memory of the stack is used to store a reference and the memory on the heap is used to store the actual object. The primitive datatypes (int, long, char etc.) are only stored on the stack.
Have you ever been debugging a Java agent using System.out.println and seen something like “java.lang.Object@bbcab38” show up in the Java debug console? What you are seeing is actually the memory address of the object and not the object itself. This happens because there is no toString() method in the object so the JVM prints out the memory address since that’s the last resort to show something unique about the object.
The below figure shows that’s on the stack and the what’s on the heap from the perspective of the simple agent shown below running in Notes/Domino. Notice how the declared int only exists on the stack.
import lotus.domino.*;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
int count=20;
} catch(Exception e) {
e.printStackTrace();
}
}
}
Of cause the above picture isn’t totally accurate since it doesn’t show all the objects created and references held by the objects on the heap but you get the picture. The lotus.domino.Database pointed to by the lotus.domino.AgentContext object is the current database, that is agentContext.getCurrentDatabase().
By reference vs. by value
In Java you only have direct access to what’s on the stack which means that what you manipulate in your agents are the references (i.e. on the stack) and not the objects themselves. This means that you in Java always program by reference and not by value. In fact there is no equivalent of the ByVal keyword in LotusScript. If you need to work on a copy of an object (i.e. ByVal) you’ll need to copy the object yourself – in Java-speak this is called cloning the object.
The Heap is qualified as garbage collectible heap. When references are lost, it’s ready to be collected for garbage.
Something to note on Notes Java agent garbage collection procedure: IBM Technote
If the primitive datatypes are held in an array it’s put in heap again – as arrays are always objects.
Yes it’s a very good point to make that arrays are always objects – even arrays of primitives such as ints.
It is howver also important to mention that calling recycle() only makes sense for Domino objects.
In the IBM echnote licked above, there is a mention about this: (Bold emphasis are mine)
“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”
It actually confuses me sometimes. But, given the negative reputation for Java agents in domino production environment, personally I would prefer to call recycle(). I think it’s harmless to call it anyway and I can possibly avoid any unpredictable consequences, since I’m no expert in this subject.
In your diagram, I believe you should have an arrow from lotus.domino.Session to lotus.domino.Database. The arrow from agentContext should go directly to the lotus.domino.Database object.
I agree that the diagram isn’t 100% correct – it does however get the point across about references and objects. Apart from the stuff you mention a lotus.domino.Agent object, representing agentContext.getCurrentAgent(), is missing as well but I had to draw the line (pun intended) somewhere… 🙂