RMI and Garbage Collection problem
Gonzalo Ortega <[email protected]> Thu, 22 Dec 2005 09:33:53 -0300
| Newsgroups | gmane.comp.java.sun.rmi |
|---|---|
| Message-ID | <[email protected]> |
We are dealing with RMI and the Garbage Collector.
Once in a while we need to execute the System.gc() method to clean-up some
data structures (WeakHashMap). Sometimes happens that a recently exported
object cannot be binded to the Registry.
After a lot of debugging and testing of rare race conditions, we came up
with the problem.
It seems that RMI doesn't hold a strong reference to the exported object
after the exportation process has finished and a local stub for the object
has been returned. This allows the Garbage Collector to collect the exported
object while it can still be reached through its local stubs. Then, when the
exported object has been collected and a method is invoked in one of its
stubs, this invocation throws a NotSuchObjectException Exception.
It turns up that RMI periodically runs the Garbage Collector explicitly (by
default each one minute).
So if an exported remote object is not properly binded to the registry, or
sent to another client in lesser than a minute after the RMI user's strong
reference to the object is lost, the exported remote object is garbage
collected and every following call to any of its stubs methods, will fail.
This seems to contradict the specification as far as the object is globally
garbage collected when stubs still exists for it.
We know several ways to overcome this problem (holding a strong reference to
the server for instance), but we are interested in knowing if this is a real
bug or just an unfortunate implementation decision.
The following code snippet shows that fact clearly:
public class Setup {
public static IRemote exportObject() throws RemoteException{
IRemote object = new IRemoteImpl();
IRemote objectStub = (IRemote) UnicastRemoteObject.exportObject(object,
10000);
// As no exception is thrown here the method succeds.
objectStub.test();
return objectStub;
}
public static void main(String[] args) {
try {
IRemote stub = exportObject();
// This call executes nicely.
stub.test();
Thread.sleep(60000);
// This call throws a nasty exception.
stub.test();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Thanks in advance for the replies.
Gonzalo Ortega.
Gustavo Petri.
===========================================================================
To unsubscribe, send email to [email protected] and include in the body
of the message "signoff RMI-USERS". For general help, send email to
[email protected] and include in the body of the message "help".
For a list of frequently asked RMI questions please refer to:
http://java.sun.com/j2se/1.3/docs/guide/rmi/faq.html
To view past RMI-USERS postings, please see:
http://archives.java.sun.com/archives/rmi-users.html