Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java RMI注册表生存期、GC等_Java_Garbage Collection_Rmi - Fatal编程技术网

Java RMI注册表生存期、GC等

Java RMI注册表生存期、GC等,java,garbage-collection,rmi,Java,Garbage Collection,Rmi,在看了Sun RMI教程之后,我一直在做一个内部Java RMI教程练习,我只是有点了解发生了什么。有一些事情对我来说似乎很奇怪,我想在对教程给出反馈之前知道到底发生了什么 本教程让我编写以下组件: 一个接口,比如说RemoteInterface,包含我们希望远程访问的方法 实现RemoteInterface的类,如RemoteServer,在其构造函数中: 通过调用LocateRegistry.createRegistry(PORTNO) 通过调用UnicastRemoteObject.e

在看了Sun RMI教程之后,我一直在做一个内部Java RMI教程练习,我只是有点了解发生了什么。有一些事情对我来说似乎很奇怪,我想在对教程给出反馈之前知道到底发生了什么

本教程让我编写以下组件:

  • 一个接口,比如说RemoteInterface,包含我们希望远程访问的方法
  • 实现RemoteInterface的类,如RemoteServer,在其构造函数中:
    • 通过调用
      LocateRegistry.createRegistry(PORTNO)
    • 通过调用
      UnicastRemoteObject.exportObject(this,PORTNO)
      并强制转换结果来创建存根RemoteInterface对象
    • 使用注册表重新绑定(BINDNAME,stub)
  • 一个类,比如ServerDemo,它有一个只创建RemoteServer实例的主方法
  • 使用BINDNAME调用服务器的客户机类,一切正常
首先,我注意到:

  • 主方法完成后,服务器继续运行。我必须明确地终止它。在我看来,它应该只是创建一个对象,然后完成,但程序不会终止,客户端仍然可以连接
  • 如果我在RemoteServer构造函数中调用
    registry.unbind(BINDNAME)
    ,客户端将停止工作,但服务器仍不会终止
  • 如果我调用
    UnicastRemoteObject.unexportObject(this,true)
    在RemoteServer构造函数中,服务器立即终止
我想知道为什么会发生这种情况——尽管如果不是这样,服务器将毫无用处,因为它会立即终止。(在我的反馈中,我将建议为ServerDemo调用RemoteServer bind和unbind方法,而不是在构造函数中执行所有绑定,从不解除绑定,并依赖服务器出于某种原因继续运行——但首先我想了解为什么会发生这种情况。)

其次,我注意到在调用
LocateRegistry.createRegistry(PORTNO)
之前,我可以调用
UnicastRemoteObject.exportObject(这个,PORTNO)
,并且一切仍然正常。我认为必须先建立注册中心,然后才能导出到它,但很明显,它并没有按照我的想法工作

我想了解一下exportObject实际上是如何工作的。(我想这与前一点有关-为什么导出对象会阻止程序结束?)


另外,如果我在一个方法中导出并绑定存根,准备在另一个方法中取消导出并解除绑定,我想知道是否需要在两者之间显式保留存根的引用。(只有BINDNAME是解除绑定所必需的。)我的一位同事报告了GC问题,虽然我自己没有注意到任何问题,但我不能排除它们,因为我没有真正了解发生了什么。默认情况下,RMI通过为每个导出的对象运行TCP服务器来工作。此服务器侦听您给定的端口,并等待某个客户端连接到该端口,然后执行被调用的方法

因此,您实际上有另一个线程在侦听这个ServerSocket,这会阻止您的应用程序退出(当没有非deamon线程运行时,Java VM会退出)


事实上,这与您的注册表没有任何关系,在您的案例中似乎根本没有使用注册表。

该注册表用于客户端-它调用
LocateRegistry.getRegistry(HOSTNAME,PORTNO)
,然后使用该注册表查找导出的对象。但是我注意到,我可以不使用
UnicastRemoteObject.exportObject
调用并绑定RemoteServer对象而不是存根,并且除了在客户端而不是服务器上准备的一些
System.out
输出外,其他一切都可以正常工作。。。现在我更困惑了:/