J'ai un problème en Java où je configure un proxy dynamique avec une interface JMX, transmettez-le à un autre composant qui appelle ensuite l'objet proxy. Lorsque je fais cela, l'application perd deux threads pour chaque appel, les threads qui ne semblent jamais expirer et continuer à construire jusqu'à ce que l'application manque de mémoire. Les threads apparaissent par paires, voir stacktrace dans la partie inférieure.les proxies dynamiques avec jmx peuvent provoquer des fuites de fil?
J'ai essayé d'utiliser certaines propriétés système légèrement obscures pour désactiver tous les délais d'attente dans JMX mais cela ne fait aucune différence. L'action clé semble être l'appel proxy dynamique. L'objet appelé via le proxy implémente Serializable, ce qui ne devrait pas poser de problème.
Lorsque je crée manuellement un bean avec une chaîne du chemin MBean et l'interface d'objet et appelez la méthode à partir de cela, le problème disparaît.
Je suis surtout à la recherche de pièges classiques quand il s'agit de proxies dynamiques, car je n'ai pas trop d'expérience avec eux.
Voici comment le proxyinstance est créé
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))));
}
et la mise en œuvre de 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();
}
}
}
Discussion stacktrace pour les deux fils (apparaissent toujours par paires):
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)
la chance J'ai cherché 'com.sun.jmx.remote.internal.ClientCommunicatorAdmin' et j'ai trouvé cette réponse en premier. –