2009-02-19 18 views
7

Ho un problema in Java, dove ho impostato un proxy dinamico con un'interfaccia JMX, lo passo su un altro componente che quindi effettua chiamate all'oggetto proxy. Quando faccio questo, l'applicazione perde due thread per ogni chiamata, thread che non sembrano mai scaduti e continuano a crescere finché l'applicazione non esaurisce la memoria.con jmx possono causare perdite di thread?

I fili vengono visualizzati a coppie, vedere lo stacktrace in basso.

Ho provato a utilizzare alcune proprietà del sistema leggermente oscure per disattivare completamente i timeout in JMX ma non fa differenza. L'azione chiave sembra essere la chiamata proxy dinamica. L'oggetto che viene chiamato attraverso il proxy implementa Serializable in modo che non dovrebbe essere un problema.

Quando si crea manualmente un bean con una stringa del percorso MBean e l'interfaccia dell'oggetto e si chiama il metodo da questo, il problema scompare.

Sono principalmente alla ricerca di trucchi classici qui quando si tratta di proxy dinamici poiché non ho troppa esperienza con loro.

Questo è come il proxyinstance viene creato

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)))); 
} 

e l'attuazione di 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 filetto per i due fili (appare sempre in coppia):

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) 

risposta

12

Il problema è stato risolto. Il problema si verifica durante la serializzazione di un oggetto sotto RemoteObject.

Quando si crea un JMXConnector, assicuratevi di chiuderlo quando hai finito di usarlo invece di lasciarlo fino a garbage collection, o sembra che possano mantenere accumulando ...

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

che fortuna Ho cercato 'com.sun.jmx.remote.internal.ClientCommunicatorAdmin' e ho trovato prima questa risposta. –

Problemi correlati