0

I have been fairly rigorous in recycling Notes Objects, but I have run into a situation where I can't recycle the object because it is passed back from a method to the calling code. So in a class I have this code:

public Database getAppDB() {
            Database appDB = null;
            try{
                Session s = ExtLibUtil.getCurrentSession();
                serverName = s.createName(s.getCurrentDatabase().getServer()).getCommon();
                appDB = s.getDbDirectory(serverName).openDatabaseByReplicaID(this.getAppRepID());
                return appDB;
            }catch (NotesException e){
                System.out.println(e.toString());
                return appDB;
            }finally{
                Utils.recycleObjects(s);
            }

        } 

Which openes a database then passes the appDB back to the calling program. Clearly if I instantiate the database in my calling program I will need to recycle it, but in this class method I can not recycle it because it is getting passed back. Am I creating a ticking time bomb with this? If so is there a way around the issue? This method could be called hundreds of time over the life cycle of session.

Bill F
  • 2,057
  • 3
  • 18
  • 39
  • Just for curiosity - what is in getAppRepID()? – Frantisek Kossuth Jul 16 '14 at 15:31
  • this method is part of the class AppProperties that is stored in a HashMap of type string, object the HashMap stores one or more Application Definitions (see http://stackoverflow.com/questions/24746448/addition-to-managed-bean-best-practice ) So the getAppRepID gets the value of the current Applications database Replica ID. the AppProperties Class stores several pieces of information about each application that can be called from the main DB. By using this method I can reuse most of my XPages and Custom Controls. 90% of the design of the Apps is common in the main DB. – Bill F Jul 16 '14 at 16:30

3 Answers3

5

Simply: the code that calls your method is responsible to recycle the database object. This rule applies to SSJS code too!

You must not recycle the session either, because it recycles all object derived from it.

Frantisek Kossuth
  • 3,524
  • 2
  • 23
  • 42
3

The Session is recycled at the end of each request and with it all descendants (Database, View, Document etc). I only tend to recycle Documents or ViewEntries in loops and DateTimes. The other thing to recycle is if your using .getColumnValues(), pass that into a Vector and recycle the column values using Session.recycle(Vector). Even if you just get one column value, it gets all. So if you have a date column, that's created as a DateTime and the only way to recycle it is with Session.recycle(Vector). Don't confuse that with Session.recycle, which recycles the Session itself. See http://www.intec.co.uk/go-green-and-recycle-the-important-information-any-non-java-xpages-dev-needs-to-know/

My preferred method of recycling now is to use the OpenNTF Domino API and let that recycle for me.

Paul Stephen Withers
  • 15,699
  • 1
  • 15
  • 33
  • So if I do this in JAVA : private Vector colVal; ..... colVal = ve.getColumnValues(); .... session.recycle(colVal); then I need to do the session recycle. Does the same hold for SSJS? – Bill F Jul 17 '14 at 23:43
  • You won't need to recycle the session itself. And yes, the same holds for SSJS – Paul Stephen Withers Jul 18 '14 at 07:41
  • It is really amazing that the issue of recycling is almost totally absent from the IBM documentation. I have never seen the session.recycle(object). I found several instances in my code as that could have been disastrous, however, in some SSJS I have this code as the values for a combo box: var rtn:Array = database.getView("vwWFSApplications").getColumnValues(0); return rtn.unshift(""); based on what you have said I should do a session.recycle(rtn) but it is the return value and would get lost. In this particular case all column values are just String, but ..... – Bill F Jul 18 '14 at 14:42
  • 1
    If the columns are all strings, you don't need to recycle. I'll do a blog post on what happens and link to it. – Paul Stephen Withers Jul 19 '14 at 10:04
  • Thanks Paul - just looked through the Mastering XPages book and recycle does not even appear in the index. – Bill F Jul 19 '14 at 16:57
  • Here's the blog post http://www.intec.co.uk/the-perils-of-getcolumnvalues-get0/. I can't remember if there's anything in Mastering XPages 2nd Edition. It may have been added. – Paul Stephen Withers Jul 20 '14 at 21:44
0

While its a great idea to be rigorous about your .recycle() calls, in this case it's unlikely to matter. No matter how many times you call this routine, if the getAppRepID returns the same replicaID, you'll keep getting a Database bound to the same C++ handle. So the greatest number of open handles you could ever have is whatever number of entries you have in your Map. Once the operation is complete and the Session recycles, all the Database handles it had will also be recycled.

Given that the number of C++ handles allowed on most server OS's these days is around 180,000 you're probably safe in your scaling. That is 180,000 for all concurrent requests, so if this process is happening simultaneously for 1000 user requests and you're putting 200 Database in the Map, you'll have problems, but I'm guessing that's unlikely.

OR you could just use the OpenNTF Domino API, which will totally eliminate this issue for you and let you delete every .recycle() call in your code.

The NTF
  • 111
  • 1