[英]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.