.recycle() in Back-end Java Classes in XPages
Tue Aug 02 14:12:59 EDT 2011
Though most of my Domino programming has been done in LotusScript (since it's one of the two "real" Domino languages), I had worked with Java here and there before diving into XPages, at least enough to know about recycle(). recycle() is a strange beast, a visitor from a non-memory-managed language popping up inside a famously memory-managed one. I get, conceptually, why it exists - since Lotus doesn't control the Java object lifecycle, Domino can never know when an object is garbage collected. And I'm sure there was some efficiency- or pragmatism-related reason why the back-end C++ objects were necessary when the Java API was created, but the result is that there's this weird anachronistic headache to deal with.
In the case of Java agents, it's not so bad - most of the time, the agent will be very procedural and so it's very easy to toss in some recycle()s in your loops and at the end of the code. However, it's much stickier with XPages, especially if you have a crazy back-end object system like I do that's meant to abstract away all of the implementation details of the Domino database. Once you reach that point, it's very hard to have code "know" when an object is no longer going to be needed. It becomes this balancing act between strict recycling on the one hand (resulting in many more round trips to the database than needed) and fast but leaky code on the other.
However, though each individual bit of code doesn't necessarily know if it's at the end of the lifecycle, there IS a well-defined set of lifecycle phases and a mechanism for hooking into that. Taking a note from how to implement a flashScope in XPages, I created a new view-scoped backing bean that inherits from a thread-safe Set containing lotus.domino.Base objects and adds a convenience method to call .recycle() on all of its contents. Then, I added a PhaseListener object to wait for after the "Render Response" phase and call that. Then, everywhere in my code that I create a Domino object, I add it to the Set before continuing along in the code. Since I'll definitely be done with all of those objects by the time the page has finished rendering, this should theoretically mean that all of my objects are recycled after each page load.