Hi. According to this: http://java.sun.com/javase/6/docs/platform/rmi/spec/rmi-arch4.html if there is no client connection to the remote object, it might be GC-ed. So, in essence, starting a new RMI server application and exporting some remote object, and then waiting for connections is wrong, isn't it? If GC runs in the time window after the server start and before the first client (which may take a week or a month), the remote object might be collected, not even the single client can connect. This seems completely broken? What is the use for that?
I know that I can store the exported object somewhere so that a hard reference point to it, making it uncollectable, but this is a workaround. The default approach seems not useful at all.
As for collecting the object in the time window after server start and before first client - suppose the server exports more remote object, and they all get clients, but one of them doesn't until after a week after starting the server. The other object do a lot of work, the JVM is not idle, so many GC-iterations occur, and it is now not that unlikely that the lone object is GC-ed.
Please season RMI users tell me what I am missing, because clearly I am missing something here. This default operation mode seems really fragile. Is Activation the only solution (apart from dirty workarounds like above).
Edward Harned wrote:1. Binding the remote object to the RMI Registry (itself a JVM) preserves the Server.
What do you mean by Server? The remote object bound? If so, this is not true - just start your app like this, leave it for a few hours, and then try to connect and use the remote object.
Also, the link I provided says:
"When a remote object is not referenced by any client, the RMI runtime refers to it using a weak reference. The weak reference allows the Java virtual machine's garbage collector to discard the object if no other local references to the object exist."
The 'weak reference' part is important here, and it means that the remote object might be garbage collected if the only reference that exists pointing to it is the weak reference in RMI's internals.
You export the implementation:
my_remoteObject = UnicastRemoteObject.exportObject(impl, port)
You save an instance of my_remoteObject in the current JVM where it will never be garbage collected.
You bind an instance of my_remoteObject to the RMI Registry.
Now you have "live" references to the remote object so it won't be GCed.
If this is not what you are talking about, then perhaps you should clarify.
Joined: Aug 21, 2008
Hi. This is exactly what I want. But this is also the workaround that I mentioned in the first post. So, in order for this to be usable, we need such a workaround of making the reference live by explicitly keeping it somewhere. So the default is unusable for long-lived server objects that might have no clients at certain times, and we should use Activation in this case. Does this hold?
You always need to keep a live reference to any object or it will be GCed. This isn't just for remote objects. For RMI I keep the reference as a Class instance and use a never-ending wait so the main() never returns: