While working on performance improvement of EJB3 deployments (EJBTHREE-1800), i have been
seeing that most of the time is spent in AOP (ex: finding annotations, creating
interceptor chains etc...).
The sample app that i am trying is 100 EJBs with 100 methods each. (The performance
degrades drastically as the number of methods increases)
One of the issues relates to the way a joinpoint for a method is created
Here's the flow:
- (AOP) Interceptor chain for EJB containers is created
- While the chain is being created, the corresponding AspectFactory are created
| protected Object createBean(ClassLoader cl) throws Throwable
| {
| ClassLoader loader = cl;
| if (loader == null)
| loader = Configurator.getClassLoader(classLoader);
| BeanInfo info = null;
| if (bean != null)
| info = configurator.getBeanInfo(bean, loader, accessMode);
|
| Joinpoint joinpoint = configurator.getConstructorJoinPoint(info, constructor,
null);
|
| ....//blah blah blah
|
| invokeLifecycle("create", create, info, loader, result);
| invokeLifecycle("start", start, info, loader, result);
|
| return result;
| }
|
The invokeLifecycle tries to call the create() and start() methods if any:
| protected void invokeLifecycle(String methodName, LifecycleMetaData lifecycle,
BeanInfo info, ClassLoader cl, Object target) throws Throwable
| {
| if (lifecycle == null || lifecycle.isIgnored() == false)
| {
| String method = methodName;
| if (lifecycle != null && lifecycle.getMethodName() != null)
| method = lifecycle.getMethodName();
| List<ParameterMetaData> parameters = null;
| if (lifecycle != null)
| parameters = lifecycle.getParameters();
| MethodJoinpoint joinpoint;
| try
| {
| joinpoint = configurator.getMethodJoinPoint(info, cl, method, parameters,
false, true);
| }
| ...// blah blah
|
The calls goes to AbstractKernelConfigurator.getMethodJoinPoint:
| public MethodJoinpoint getMethodJoinPoint(BeanInfo info, ClassLoader cl, String
name, List<ParameterMetaData> parameters, boolean isStatic, boolean isPublic) throws
Throwable
| {
| return Configurator.findMethod(info, cl, name, parameters, isStatic, isPublic);
| }
|
The findMethod ultimately leads to this implementation in
org.jboss.joinpoint.plugins.Config
| public static MethodInfo findMethodInfo(ClassInfo classInfo, String name, String[]
paramTypes, boolean isStatic, boolean isPublic, boolean strict) throws JoinpointException
| {
|
| ...// blah blah
|
| MethodInfo result = locateMethodInfo(current, name, paramTypes, isStatic,
isPublic, strict);
| if (result != null)
| return result;
| current = current.getSuperclass();
| }
|
The implementation for locateMethodInfo looks unnecessarily expensive:
| private static MethodInfo locateMethodInfo(ClassInfo classInfo, String name, String[]
paramTypes, boolean isStatic, boolean isPublic, boolean strict)
| {
| MethodInfo[] methods = classInfo.getDeclaredMethods();
| if (methods != null)
| {
| for (int i = 0; i < methods.length; ++i)
| {
| if (name.equals(methods[ i].getName()) &&
| equals(paramTypes, methods[ i].getParameterTypes()) &&
| (strict == false || (methods[ i].isStatic() == isStatic &&
methods[ i].isPublic() == isPublic)))
| return methods[ i];
| }
| }
| return null;
| }
|
This locateMethodInfo is passed with the method name and params, so any specific reason
why it needs to get all the declared methods and then do a equals on them instead of using
the other API on ClassInfo which accepts the method name and params:
MethodInfo getDeclaredMethod(String name, TypeInfo[] parameters);
The current implementation leads to a performance degradation when the number of methods
increases (All this piece of code is trying to do is find a couple of methods named
create() and start()).
View the original post :
http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4228711#...
Reply to the post :
http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&a...