Skip to content

Commit 961cd76

Browse files
committed
CLOUDSTACK-6859:Management Server PermGen run out of memory after some
time due to class leak.
1 parent e9ebe6e commit 961cd76

1 file changed

Lines changed: 35 additions & 27 deletions

File tree

framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@
2121

2222
import java.lang.reflect.InvocationTargetException;
2323
import java.lang.reflect.Method;
24+
import java.util.HashMap;
25+
import java.util.Map;
2426

25-
import net.sf.cglib.proxy.Callback;
26-
import net.sf.cglib.proxy.CallbackFilter;
2727
import net.sf.cglib.proxy.Enhancer;
28+
import net.sf.cglib.proxy.Factory;
2829
import net.sf.cglib.proxy.MethodInterceptor;
2930
import net.sf.cglib.proxy.MethodProxy;
3031

@@ -39,6 +40,7 @@ public class AsyncCallbackDispatcher<T, R> implements AsyncCompletionCallback {
3940
private Object _contextObject;
4041
private Object _resultObject;
4142
private AsyncCallbackDriver _driver = new InplaceAsyncCallbackDriver();
43+
private static Map<Class, Enhancer> enMap = new HashMap<Class, Enhancer>();
4244

4345
private AsyncCallbackDispatcher(T target) {
4446
assert (target != null);
@@ -58,39 +60,45 @@ public Method getCallbackMethod() {
5860

5961
@SuppressWarnings("unchecked")
6062
public T getTarget() {
61-
Enhancer en = new Enhancer();
62-
6363
Class<?> clz = _targetObject.getClass();
6464
String clzName = clz.getName();
6565
if (clzName.contains("EnhancerByCloudStack"))
6666
clz = clz.getSuperclass();
6767

68-
en.setSuperclass(clz);
69-
en.setCallbacks(new Callback[] {new MethodInterceptor() {
70-
@Override
71-
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
72-
_callbackMethod = arg1;
73-
_callbackMethod.setAccessible(true);
74-
return null;
75-
}
76-
}, new MethodInterceptor() {
77-
@Override
78-
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
79-
return null;
80-
}
81-
}});
82-
en.setCallbackFilter(new CallbackFilter() {
83-
@Override
84-
public int accept(Method method) {
85-
if (method.getParameterTypes().length == 0 && method.getName().equals("finalize")) {
86-
return 1;
87-
}
88-
return 0;
68+
69+
Enhancer en = null;
70+
synchronized (enMap) {
71+
en = enMap.get(clz);
72+
if (en == null) {
73+
en = new Enhancer();
74+
75+
en.setSuperclass(clz);
76+
en.setCallback(new MethodInterceptor() {
77+
@Override
78+
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
79+
return null;
80+
}
81+
});
82+
enMap.put(clz, en);
8983
}
90-
});
84+
}
9185

9286
try {
93-
return (T)en.create();
87+
T t = (T)en.create();
88+
Factory factory = (Factory)t;
89+
factory.setCallback(0, new MethodInterceptor() {
90+
@Override
91+
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
92+
if (arg1.getParameterTypes().length == 0 && arg1.getName().equals("finalize")) {
93+
return null;
94+
} else {
95+
_callbackMethod = arg1;
96+
_callbackMethod.setAccessible(true);
97+
return null;
98+
}
99+
}
100+
});
101+
return t;
94102
} catch (Throwable e) {
95103
s_logger.error("Unexpected exception", e);
96104
}

0 commit comments

Comments
 (0)