DGC Behaving unexpectedly
I have an RMI application in which objects on the server are not being garbage collected as I have been led to believe should happen.
Generally speaking, the server consists of an instance of a 'factory' class [call it MyObjFactory] object that is bound to the Registry. The client creates instances of another Remote class [call it MyObj] through this 'factory'. The client uses the MyObj and then calls a free() method to indicate when it is finished with it, and then releases all references to the MyObj stub. The free() method triggers the server to call unexportObject() and release all references to the MyObj.
The application has been working for a year or more, but as demand increases, it has become apparent that memory usage is a problem. Using a heap analysis tool and verbose dgc, I have discovered that although the server has no strong references to the MyObj instances, they hang around indefinitely because the client continues to renew leases for them despite the fact that it has set all stub references = null!
In a test scenario I have my client locate the factory create 1000 MyObj instances and immediately free() them:
// in the MyObjImpl class:
public void free()
{
UnicastRemoteObject.unexportObject(this,true); // i know this is working because if the client
// tries to use the object afterwards, a
// NoSuchObjectException occurs
localFactory.removeMe(this); // destroys the ONLY server-side reference to this instance
}
// test loop on client:
MyObjFactory factory = registry.lookup("MyObjFactory");
for (int i = 1; i <= 1000; i++)
{
MyObj obj = factory.createNew();
obj.free();
obj = null;
}
After this finishes running, there are 0 (zero) instances of the stub remaining on the client side [as you would expect]. However, 1000 MyObjImpl instances continue to live on the server side,I have confirmed this through heap analysis.
Meanwhile dirty() calls continue to be received for these 1000 objects. I have confirmed this also by using sun.rmi.dgc.logLevel=VERBOSE and also by examining the lease expiry time which continues to be updated. Oh, and by the way, I set the leaseValue and checkInterval to 5000 ms to speed up the results of my test.
NOW THE INTERESTING PART: When i forcefully terminate the client, the leases eventually DO expire and the MyObjImpl instances are gc'd. So there are obviously some references to their stubs on the client - but they are definitely NOT strong references!
Can anyone suggest what more i can do to prevent the persistent lease renewals that are preventing these unused resources from being gc'd on the server side? I have read something about 'Phantom References' - could this be part of the problem? I don't even need the DGC because I feel I am managing object lifespan effectively myself. Is there any way to disable DGC and all of its leasing shinanigans?

