문제

JAVA에 JMX 인터페이스가있는 동적 프록시를 설정하는 문제가 있는데,이를 다른 구성 요소로 전달하여 프록시 객체를 호출합니다. 이 작업을 수행하면 응용 프로그램은 각 호출마다 두 개의 스레드를 누출합니다. 스레드는 시간이 오래 걸리지 않는 것처럼 보이며 응용 프로그램이 메모리가 부족할 때까지 계속 쌓입니다.

스레드는 쌍으로 나타납니다. 하단의 스택 트레이스를 참조하십시오.

약간 모호한 시스템 속성을 사용하여 JMX에서 타임 아웃을 끄는 것을 시도했지만 차이는 없습니다. 핵심 조치는 동적 프록시 호출 인 것 같습니다. 프록시를 통해 호출되는 객체는 직렬화 가능성을 구현하여 문제가되지 않아야합니다.

mbean 경로의 문자열과 객체 인터페이스가있는 콩을 수동으로 만들고 그 중 메소드를 호출하면 문제가 사라집니다.

나는 그들에 대한 경험이 너무 많지 않기 때문에 역동적 인 프록시와 관련하여 주로 고전적인 Gotchas를 찾고 있습니다.

이것이 근위가 생성되는 방식입니다

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

그리고 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();
    }
}

}

두 스레드의 스레드 스택 트레이스 (항상 쌍으로 나타납니다) :

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)
도움이 되었습니까?

해결책

문제가 해결되었습니다. remoteObject 아래의 물체를 직렬화하는 동안 문제가 나타납니다.

당신이 만들 때 JMXConnector, 쓰레기 수집에 남겨 두지 말고 사용을 완료 할 때 닫으십시오.

JMXConnector connector = JMXConnectorFactory.connect(url);
//...
connector.close();
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top