簡體   English   中英

使用jmx的動態代理會導致線程泄漏嗎?

[英]dynamic proxies with jmx can cause thread leaks?

我在Java中遇到問題,我在其中設置了一個帶有JMX接口的動態代理,將其傳遞給另一個組件,然后調用代理對象。 當我這樣做時,應用程序為每個調用泄漏兩個線程,線程似乎永遠不會超時並繼續構建,直到應用程序內存不足。

線程成對出現,請參見底部的stacktrace。

我曾嘗試使用一些略顯模糊的系統屬性來關閉JMX中的超時,但它並沒有什么區別。 關鍵動作似乎是動態代理調用。 通過代理調用的對象實現Serializable,因此不應該是一個問題。

當我手動創建一個包含MBean路徑和對象接口的字符串的Bean並從中調用該方法時,問題就消失了。

在動態代理方面,我主要是在尋找經典的問題,因為我沒有太多的經驗。

這就是創建proxyinstance的方式

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))));
}

和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();
    }
}

}

兩個線程的線程堆棧跟蹤(總是成對出現):

Name: JMX server connection timeout 53
State: TIMED_WAITING on [I@18bbe70
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)

問題已經解決了。 在RemoteObject下面的對象序列化過程中出現問題。

當你創建一個JMXConnector時 ,確保在你完成使用它時關閉它,而不是把它留給垃圾收集,或者看起來它們可以繼續堆積......

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM