Mam problem w Javie, gdzie skonfigurowałem dynamiczny serwer proxy z interfejsem JMX, przekazuję to do innego komponentu, który następnie wywołuje obiekty proxy. Kiedy to zrobię, aplikacja wycieknie dwa wątki dla każdego połączenia, wątki, które nigdy nie wydają się wygasać i będą budowane aż do wyczerpania pamięci.dynamiczne proxy z jmx może powodować przecieki nici?
Gwinty pojawiają się w parach, patrz stacktrace u dołu.
Próbowałem użyć nieco mało znanych właściwości systemu do całkowitego wyłączenia limitu czasu w JMX, ale nie ma to znaczenia. Kluczowym działaniem wydaje się dynamiczne wywołanie proxy. Obiekt, który jest wywoływany przez proxy, obsługuje Serializable, więc nie powinno to stanowić problemu.
Gdy ręcznie utworzę element Bean z ciągiem ścieżki komponentu MBean i interfejsem obiektu, a metoda zostanie wywołana, problem zniknie.
W poszukiwaniu dynamicznych serwerów proxy szukam głównie klasycznych gier, ponieważ nie mam z nimi zbyt dużego doświadczenia.
ten sposób proxyinstance jest tworzony
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))));
}
i realizację 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();
}
}
}
StackTrace wątku dla dwóch wątków (zawsze występują w parach):
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)
jak szczęście Szukałem "com.sun.jmx.remote.internal.ClientCommunicatorAdmin" i najpierw znalazłem tę odpowiedź. –