2009-02-19 9 views
7

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) 

Odpowiedz

12

Problem został rozwiązany. Problem pojawia się podczas serializacji obiektu poniżej RemoteObject.

Podczas tworzenia JMXConnector, upewnij się, aby go zamknąć, gdy skończysz go używać zamiast pozostawiać go do zbierania śmieci, albo wydaje się mogą zachować piętrzą się ...

JMXConnector connector = JMXConnectorFactory.connect(url); 
//... 
connector.close(); 
+0

jak szczęście Szukałem "com.sun.jmx.remote.internal.ClientCommunicatorAdmin" i najpierw znalazłem tę odpowiedź. –

Powiązane problemy