[jboss-jira] [JBoss JIRA] (AS7-4675) Memory leak when reading EJB 2.1 CMP EntityBeans

Tiago Frazão (JIRA) jira-events at lists.jboss.org
Wed Aug 21 10:59:27 EDT 2013


    [ https://issues.jboss.org/browse/AS7-4675?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12798255#comment-12798255 ] 

Tiago Frazão commented on AS7-4675:
------------------------------------

Stuart,

I took a look at the BasicComponent class, which is responsible to create all interceptors for all method in LocalEntity and i suspect the problem is the creation of interceptors for all methods, which I don't use.

In our code we only call set(s) and gets(), using ValueObject Pattern (setValues(VO) and getValues()), then the idea is to create the interceptor dynamicaly, in other words, the BasicComponent will receive the map of interceptor factories so internally it can create the interceptors when the method is invoked.

I would like to know if is there any negative impact about this approach ?

class BasicComponentInstance {
 ...
 //
 // final Map<Method, InterceptorFactory> interceptorFactoryMap = this.getInterceptorFactoryMap();
 //         // This is an identity map.  This means that only <b>certain</b> {@code Method} objects will
 //         // match - specifically, they must equal the objects provided to the proxy.
 //         final IdentityHashMap<Method, Interceptor> interceptorMap = new IdentityHashMap<Method, Interceptor>();
 //         for (Method method : interceptorFactoryMap.keySet()) {
 //             interceptorMap.put(method, interceptorFactoryMap.get(method).create(context));
 //         }

 ...

 // create the component instance
   final BasicComponentInstance basicComponentInstance = 
            this.instantiateComponentInstance(instanceReference, 
                                 componentInstancePreDestroyInterceptor, 
                                 this.getInterceptorFactoryMap(),  // ---> We pass the factories not the interceptors instances
                                 context);



}

class BasicComponentInstance {
    protected BasicComponentInstance(final BasicComponent component,
			final AtomicReference<ManagedReference> instanceReference,
			final Interceptor preDestroyInterceptor,
			final Map<Method, InterceptorFactory> interceptorFactoryMap,
			final InterceptorFactoryContext context // --> We are passing the context use by the factory
                ) {
		// Associated component
		this.component = component;
		this.instanceReference = instanceReference;
		this.preDestroy = preDestroyInterceptor;
		this.interceptorFactoryMap = interceptorFactoryMap;
		this.context = context;
	}


    public Interceptor getInterceptor(final Method method) throws IllegalStateException {
        //Interceptor interceptor = methodMap.get(method);
        // Here we will get the interceptor factory for the method trigged. (on demand)
        
        InterceptorFactory interceptorFactory = this.interceptorFactoryMap.get(method);

        if (!this.methodMap.containsKey(method)) {
		this.methodMap.put(method, interceptorFactory.create(this.context));
	}

	Interceptor interceptor = this.methodMap.get(method);
	if (interceptor == null) {
		throw MESSAGES.methodNotFound(method);
	}
	return interceptor;
    }

}


                
> Memory leak when reading EJB 2.1 CMP EntityBeans
> ------------------------------------------------
>
>                 Key: AS7-4675
>                 URL: https://issues.jboss.org/browse/AS7-4675
>             Project: Application Server 7
>          Issue Type: Bug
>          Components: EJB
>    Affects Versions: 7.1.1.Final
>         Environment: Windows 7 Pro SP1 (64bit);  JDK 1.6.0_31 (64bit); Oracle Database 11g Release 11.1.0.6.0 - 64bit Production; AS71.1Final / AS71.2 latest build
>            Reporter: Klaus Benary
>            Assignee: Stuart Douglas
>            Priority: Critical
>             Fix For: 7.1.2.Final (EAP)
>
>         Attachments: HeapDumpScreenShot.png, JCTest-maven.zip, JCTest.zip
>
>
> After reading 12000 EJB 2.1 EntityBeans in a test application there are about 5 million Interceptor[] arrays firmely bound in the heap. A heap dump shows this as a typical reference chain:
> GC Root: ServiceContainerImpl$ServiceThread
> ServiceContainerImpl$ServiceThread.container = ServiceContainerImpl
>  ServiceContainerImpl.registry = UnlockedReadHashMap
>   UnlockedReadHashMap.table = AtomicReferenceArray
>    AtomicReferenceArray.array = Object[16384]
>     Object[6209] = UnlockedReadHashMap$Item[3]
>      UnlockedReadHashMap$Item[1] = UnlockedReadHashMap$Item
>        UnlockedReadHashMap$Item.value = ServiceRegistrationImpl
>         ServiceRegistrationImpl.instance = ServiceControllerImpl
>          ServiceControllerImpl.serviceValue = ImmediateValue
>           ImmediateValue.value = TimedObjectInvokerImpl
>             TimedObjectInvokerImpl.timeoutInterceptors = HashMap
>               HashMap.table = HashMap$Entry[128]
>                HashMap$Entry[123] = HashMap$Entry
>                 HashMap$Entry.value = ChainedInterceptor
>                   ChainedInterceptor.interceptors = Arrays$ArrayList
>                    Arrays$ArrayList.a = Interceptor[6]
> The number of bound objects keeps growing when reading more EntityBeans - even wehn reading the same beans again.
> Even after undeploy of the application the 

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira



More information about the jboss-jira mailing list