Để tạo một câu chuyện dài ngắn, tôi gặp khó khăn khi nhận một vài chuỗi không phải daemon của RMI của Java để đóng sau khi ứng dụng của tôi không còn cần RMI nữa. Điều này ngăn không cho JVM thoát khi main() hoàn thành.RMI Chủ đề ngăn JVM thoát ra sau khi main() hoàn thành
Tôi hiểu rằng việc xuất UnicastRemoteObject
s sẽ khiến RMI rời khỏi chuỗi mở cho đến khi bạn gọi thành công UnicastRemoteObject.unexportObject(Object o,boolean force)
. Dưới đây là một ví dụ (chạy mà không sửa đổi và JVM sẽ thoát bình thường - loại bỏ các cuộc gọi đến unexportObject và JVM sẽ không bao giờ thoát):
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class TestUnicastRemoteObject{
private static UnicastRemoteObject obj;
private static Registry registry;
public static void main(String[] args) throws Exception{
obj = new UnicastRemoteObject(){
private static final long serialVersionUID = 1L;
};
System.err.println("created UnicastRemoteObject");
System.err.println("creating registry ...");
registry = LocateRegistry.createRegistry(9999);
System.err.println("registry created.");
System.err.println("binding obj to registry ...");
registry.bind("Test", obj);
System.err.println("bound");
UnicastRemoteObject.unexportObject(obj, true);
System.err.println("unexported obj");
}
}
Ngoài ra, nó dường như không quan trọng cho dù bạn tạo registry và/hoặc gắn kết đối tượng từ xa với nó - điều duy nhất có vẻ quan trọng trong ví dụ này là bất cứ khi nào bạn tạo một UnicastRemoteObject, bạn cần gọi unexportObject
để ngăn chặn bất kỳ luồng nào còn lại sau khi bạn hoàn thành. Trong ứng dụng của tôi, tôi đã chắc chắn rằng tôi đã gọi unexportObject trên mỗi UnicastRemoteObject tôi tạo ra, nhưng chuỗi RMI "reaper" và "connection accept" vẫn tồn tại, ngăn không cho JVM của tôi thoát khi ứng dụng của tôi kết thúc bằng tài nguyên RMI.
Có điều gì khác có thể khiến RMI rời khỏi chủ đề phía sau, ngoài việc quên để unexport UnicastRemoteObjects không?
Chương trình thử nghiệm đó có được treo không? Bạn đang sử dụng JRE nào? Bạn đã thử> = 1,6 chưa? Có phải "reaper" và "connection-accept" thực sự là các chủ đề không phải daemon duy nhất còn lại không? – Gray
Có - hai chủ đề này là những chủ đề duy nhất còn lại khi tôi hồ sơ ứng dụng. Chương trình thử nghiệm được cho là tiếp tục chạy sau khi hoàn thành chính, khi bạn nhận xét cuộc gọi đến 'UnicastRemoteObject.unexportObject (obj, true)'. Hành vi mong muốn là dành cho chương trình thử nghiệm để thoát. Tôi nghi ngờ tôi có thể thiếu một cuộc gọi đến unexportObject một nơi nào đó, nhưng chỉ tò mò nếu có bất kỳ cách nào khác để lại RMI chủ đề chạy. – CodeBlind
Và có, tôi đang chạy cả Java 1.6 và 1.7 - hành vi này giống nhau trong cả hai phiên bản. – CodeBlind