JDK-6354718 : client connections to ORB are neither freed nor garbage collected (java 1.5)
  • Type: Bug
  • Component: other-libs
  • Sub-Component: corba:orb
  • Affected Version: 1.0.1,5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: generic,solaris_9
  • CPU: generic,sparc
  • Submitted: 2005-11-23
  • Updated: 2011-02-16
  • Resolved: 2010-10-07
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
5.0u10Fixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Description
A DESCRIPTION OF THE REQUEST :
If a client connection to an ORB (omniORB in this case) is established from an application (i.e. a servlet) running under Tomcat (i.e. this app is running for weeks w/o being restarted) and all work with the orb is done, the connection to the orb should be released and all resources should be freed (especially the occupied port of course).

Though the recommendation in bug # 6210230 says to let the garbage collector clean up everything, this does not work:
- I ensured that no more refs to objRef are available (refs are explicitly set to null)
- the respective finalize() methods are called - but the connection remains established until either Tomcat is stopped/started or the server part of the application (bound to the orb) is restarted.

Though "objRef._release()", "orb.shutdown(false)" and "orb.destroy()" are called the ports to the orb remain occupied: objRef is the client stub created from the idlj compiler - and objRef extends ObjectImpl where "ObjectImpl._release()" calls "_get_delegate().release(this)". The Delegate is in my case a com.sun.corba.se.impl.protocol.CorbaClientDelegateImpl object whose "release()" method is EMPTY.

There is no method available which can be called to release the resources in use.

Main problem: after a certain ammount of time, all ports are taken and it is not possible anymore to connect to the orb until - as described - either the server part or tomcat is restarted. (verified that the ports are taken with lsof (list open files) 4.73)



JUSTIFICATION :
  To free up connections (i.e. close sockets) between orb client and server application and to avoid that all available system resources remain allocated.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
have a "disconnect()" or "release()" or "close()" method for client stubs as well - and not only the "orb.disconnect(servant)" method which can't be used for _is_local() == false objects as well.
ACTUAL -
client connections to orb remain open and aren't garbage collected

---------- BEGIN SOURCE ----------
my.package objRef = null;

private void init(){
  org.omg.CORBA.ORB orb = ORB.init(args, props);
  // get the root naming context
  org.omg.CORBA.Object obj = orb.resolve_initial_references("name");
  NamingContextExt nce=NamingContextExtHelper.narrow(obj);
  objRef = "whatever"Helper.narrow(nce.resolve_str("service-name"));
  // where "whatever" is the Helper class created from the idlj compiler.
}

// do some work with the client application....

private void release(){
  if(objRef!=null){
    ORB orb = (ObjectImpl)objRef)._orb();
    if(orb!=null){
      // causes exception in java 1.5.0,
      // but used to work and cleaned up connections in java < 1.5
//      orb.disconnect(objRef);
      orb.shutdown(false);
      orb.destroy();
    }
    objRef._release();
  }
  objRef=null;
  orb=null;
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
unfortunately there is no workaround except not upgrading to java 1.5 :-(

Comments
EVALUATION Yes. It's a known bug in ORB connection management. What's happening here is, the connectionCache that maintains both inbound and outbound connections does not reclaim connections, upon ORB destroy() call. There is a connection reclaim() logic in place, but does not kick in, until it reaches certain watermark levels. Since, a single client can have a multiple ORBs and thereby multiple outbound connections (in the reported case) , with each cache having exactly one connection which leaks up on ORB exit. This leak multiplies based on the number of ORBs and time period over which client stays live, up and running. The solution is, to walk through the connection cache and close each connection, no matter what the watermark levels are. This can be done at the corba transport manager close() call.
16-06-2006