Java – can dynamic proxies using JMX cause thread leaks?

I encountered problems in Java, where I set up a dynamic proxy with JMX interface, passing it to another component, and then calling the proxy object. When I do this, the application leaks two threads for each call. The threads never seem to time out and continue to build until the application runs out of memory

Threads appear in pairs, see stacktrace at the bottom

I've tried to use some slightly vague system properties to completely turn off timeouts in JMX, but it doesn't make any difference The key action seems to be dynamic proxy calls Serializable is implemented through the object called by proxy, so it should not be a problem

The problem disappeared when I manually created a Bean containing the MBean path and the object interface and invoked the method from it.

Because I don't have much experience in them, I'm mainly looking for the classic problems of dynamic agents

This is how you create a 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))));
}

Implementation of and 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();
    }
}

}

Thread stack trace for two threads (always in pairs):

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)

Solution

The problem has been solved There was a problem during object serialization under remoteobject

When you create a JMX connector, make sure to close it when you're finished using it, instead of leaving it to garbage collection, or it looks like they can continue to pile up

JMXConnector connector = JMXConnectorFactory.connect(url);
//...
connector.close();
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>