2009-02-19 24 views
7

Tôi có một vấn đề trong Java, nơi tôi thiết lập một proxy năng động với một giao diện JMX, chuyển này vào một thành phần khác mà sau đó thực hiện cuộc gọi đến đối tượng proxy. Khi tôi làm điều này, ứng dụng sẽ rò rỉ hai luồng cho mỗi cuộc gọi, các luồng không bao giờ có vẻ hết thời gian và tiếp tục xây dựng cho đến khi ứng dụng hết bộ nhớ.proxy động với jmx có thể gây rò rỉ luồng?

Chủ đề xuất hiện theo cặp, xem stacktrace ở dưới cùng.

Tôi đã thử sử dụng một số thuộc tính hệ thống hơi tối nghĩa để tắt hết thời gian chờ trong JMX nhưng không tạo sự khác biệt. Hành động chính có vẻ là cuộc gọi proxy động. Các đối tượng được gọi là thông qua proxy thực hiện Serializable do đó không phải là một vấn đề.

Khi tôi tạo thủ công Bean bằng một chuỗi đường dẫn MBean và giao diện đối tượng và gọi phương thức từ đó, sự cố sẽ biến mất.

Tôi hầu như đang tìm kiếm các màn hình cổ điển ở đây khi nói đến proxy động vì tôi không có quá nhiều kinh nghiệm với chúng.

Đây là cách proxyinstance được tạo ra

public <T> T create(final Class<T> type, 
     final Object... nameParameters) throws JmxConnectionException { 
    return type.cast(Proxy.newProxyInstance(
      type.getClassLoader(), 
      new Class<?>[] {type}, 
      new MyInvocationHandler(this, 
        fill(nameOf(type), nameParameters)))); 
} 

và thực hiện các MyInvocationHandler:

final class MyInvocationHandler implements InvocationHandler, Serializable { 
private static final long serialVersionUID = 0L; //actually a proper random long 
private final transient ProxyFactory proxyFactory; 
private String mBeanName; 
private RemoteObject remoteObject; 

MyInvocationHandler(final ProxyFactory proxyFactory, 
     final String mBeanName) { 
    this.proxyFactory = proxyFactory; 
    this.mBeanName = mBeanName; 
} 

private void writeObject(final ObjectOutputStream out) 
throws IOException { 
    try { 
     checkConnected(); 
    } catch (final JmxConnectionException e) { 
     throw new IOException(e); 
    } 
    out.writeObject(mBeanName); 
    out.writeObject(remoteObject); 
} 

private void readObject(final ObjectInputStream in) 
throws IOException, ClassNotFoundException { 
    mBeanName = (String) in.readObject(); 
    remoteObject = (RemoteObject) in.readObject(); 
} 

public Object invoke(final Object proxy, final Method method, 
     final Object[] args) throws Throwable { 
    checkConnected(); //Just checks that the RemoteObject isn't null. 
    try { 
     return invokeMethod(method, args); // Calls the method on the remoteObject with the arguments, code cut. 
    } catch (final InvocationTargetException e) { 
     throw e.getCause(); 
    } 
} 

}

Chủ đề stacktrace cho hai chủ đề (luôn xuất hiện trong cặp):

Name: JMX server connection timeout 53 
State: TIMED_WAITING on [[email protected] 
Total blocked: 3 Total waited: 4 

Stack trace: 
java.lang.Object.wait(Native Method) 
com.sun.jmx.remote.internal.ServerCommunicatorAdmin$Timeout.run(ServerCommunicatorAdmin.java:150) 
java.lang.Thread.run(Thread.java:619) 

Name: Thread-21 
State: TIMED_WAITING 
Total blocked: 0 Total waited: 1 

Stack trace: 
java.lang.Thread.sleep(Native Method) 
com.sun.jmx.remote.internal.ClientCommunicatorAdmin$Checker.run(ClientCommunicatorAdmin.java:154) 
java.lang.Thread.run(Thread.java:619) 

Trả lời

12

Sự cố đã được giải quyết. Sự cố xuất hiện trong quá trình tuần tự hóa đối tượng bên dưới RemoteObject.

Khi bạn tạo một JMXConnector, hãy chắc chắn để đóng nó lại khi bạn sử dụng xong chứ không phải rời khỏi nó lên đến thu gom rác thải, hoặc có vẻ như họ có thể giữ chồng chất ...

JMXConnector connector = JMXConnectorFactory.connect(url); 
//... 
connector.close(); 
+0

may mắn làm sao Tôi đã tìm kiếm 'com.sun.jmx.remote.internal.ClientCommunicatorAdmin' và tìm thấy câu trả lời này trước tiên. –

Các vấn đề liên quan