简体   繁体   English

Java:RMI目标对象的垃圾收集?

[英]Java: garbage collection for RMI target object?

While getting my hands dirty with RMI, I got a java.rmi.NoSuchObjectException exception, which led me to this question: java.rmi.NoSuchObjectException: no such object in table but my question is different . 虽然让我的手弄脏了RMI,但是我得到了一个java.rmi.NoSuchObjectException异常,这引出了我的问题: java.rmi.NoSuchObjectException:表中没有这样的对象, 但我的问题是不同的

I'm creating the impl object in my main method and hence in the main thread. 我正在我的main方法中创建impl对象,因此在主线程中。 If I do this: 如果我这样做:

FooImpl fi = new FooImpl();
foo = (Foo) UnicastRemoteObject.exportObject(fi, 0);

things work fine. 事情很好。

If I do this: 如果我这样做:

foo = (Foo) UnicastRemoteObject.exportObject(new FooImpl(), 0);

I see that FooImpl instance is collected and then I get the aforementioned exception. 我看到收集了FooImpl实例,然后我得到了上述异常。

foo is a static reference that I'm initializng in main; foo是我在main中初始化的静态引用; and another remote object returns foo from one of its methods. 另一个远程对象从其中一个方法返回foo So a client gets that remote object first, then gets foo from it, and then calls a method on foo and that's when I get the exception as explained above. 因此,一个客户端获取远程对象,然后再获取foo从它,然后调用一个方法foo ,这时候我得到的异常如上所述。 So why is it happening this way? 那么为什么会这样呢?

EDIT: here's my main method 编辑:这是我的主要方法

public static void main(String[] args) throws RemoteException, AlreadyBoundException 
{

    Server server = new Server();
    Hello stub = (Hello) UnicastRemoteObject.exportObject(server, 0);

    FooImpl fi = new FooImpl();
    foo = (Foo) UnicastRemoteObject.exportObject(fi, 0);

    Registry registry = LocateRegistry.getRegistry();
    registry.bind("Hello", stub);       
    System.out.println("Server ready!");        
}

In client, I'm getting hello and calling a method on it which gives me foo and then calling a method on foo . 在客户端,我正在hello并在其上调用一个方法,它给了我foo然后在foo上调用一个方法。

EDIT2: If I use 编辑2:如果我使用

Hello stub = (Hello) UnicastRemoteObject.exportObject(new Server(), 0);

and bind foo first and then hello , then same exception is thrown when I try to access hello because now it's Server instance which is getting collected. 首先绑定foo然后再hello ,然后当我尝试访问hello时抛出相同的异常,因为现在它正在收集的Server实例。 Really weird stuff! 真奇怪的东西!

Both approaches are liable to fail. 两种方法都可能失败。 There's no real difference between them in terms of variable scoping. 在变量范围方面,它们之间没有真正的区别。

The problem more usually seen in these situations is the Registry itself, when created by LocateRegistry.createRegistry() , which you aren't doing. 在这些情况下更常见的问题是注册表本身,当由LocateRegistry.createRegistry()创建时,您没有这样做。 If you were, the created Registry itself can be GC'd too: you must keep the Registry reference in a static variable. 如果是,创建的注册表本身也可以是GC:您必须将Registry引用保留在静态变量中。 Then it won't be GC'd, and it will prevent the stub foo from being GC'd, and the stub will keep the FooImpl from being DGC'd and therefore GC'd. 然后它将不会是GC,它将阻止stub foo被GC'd,并且存根将保持FooImpl不被DGC并因此GC'd。

In your case you would be better off keeping the remote object references (servers, not stubs) in static variables. 在您的情况下,最好将远程对象引用(服务器,而不是存根)保留在静态变量中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM