Ste*_*erg 7 java multithreading jmx proxy-classes
我在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))));
}
Run Code Online (Sandbox Code Playgroud)
和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();
}
}
Run Code Online (Sandbox Code Playgroud)
}
两个线程的线程堆栈跟踪(总是成对出现):
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)
Run Code Online (Sandbox Code Playgroud)
Ste*_*erg 12
问题已经解决了.在RemoteObject下面的对象序列化过程中出现问题.
当你创建一个JMXConnector时,确保在你完成使用它时关闭它,而不是把它留给垃圾收集,或者看起来它们可以继续堆积......
JMXConnector connector = JMXConnectorFactory.connect(url);
//...
connector.close();
Run Code Online (Sandbox Code Playgroud)