7
我在Java中有一個問題,我使用JMX接口設置動態代理,將其傳遞給另一個組件,然後調用代理對象。當我這樣做時,應用程序會爲每個調用泄漏兩個線程,這些線程永遠不會超時,並在應用程序內存不足時繼續構建。使用jmx的動態代理會導致線程泄漏?
線程成對出現,請參閱底部的堆棧跟蹤。
我曾嘗試使用一些稍微模糊的系統屬性來關閉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 [[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)
多麼的幸運我搜索了`com.sun.jmx.remote.internal.ClientCommunicatorAdmin`,並首先找到了這個答案。 – 2014-06-25 04:50:22