[ 
https://issues.apache.org/jira/browse/TOMEE-4120?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17646254#comment-17646254
 ] 

Thomas Lien commented on TOMEE-4120:
------------------------------------

Here's some additional info. The below code segments show the population of 
this liveRegistryMap in openejb package org.apache.openejb.client. It actually 
gets added to the map twice in the same findByPrimaryKey invocation. Once in 
the constructor that gets called when creating on the handler on 
EntityEJBHomeHandler line 57 and the other on line 59. I don't see any way that 
these gets cleaned up unless the entity is removed (invalidateAllHandlers). 
Being a HashSet of WeakReference would not help either. At best it would set 
the referent of the WeakReference to null which still leaves a large HashSet of 
null WeakReferences. But I'm not even seeing the WeakReference referents go to 
null, meaning there must be other non-weak references to the handler as well.

Trace of first spot where this liveRegistryMap is populated
{code:java}
EJBInvocationHandler.registerHandler(Object, EJBInvocationHandler) line: 205    
EntityEJBObjectHandler.<init>(ThreadPoolExecutor, EJBMetaDataImpl, 
ServerMetaData, ClientMetaData, Object, JNDIContext$AuthenticationInfo) line: 
40     
EJBObjectHandler.createEJBObjectHandler(ThreadPoolExecutor, EJBMetaDataImpl, 
ServerMetaData, ClientMetaData, Object, JNDIContext$AuthenticationInfo) line: 
100  
EntityEJBHomeHandler.findX(Method, Object[], Object) line: 57   
EntityEJBHomeHandler(EJBHomeHandler)._invoke(Object, Method, Object[]) line: 
136        
EntityEJBHomeHandler(EJBInvocationHandler).invoke(Object, Method, Object...) 
line: 136  
Jdk13InvocationHandler.invoke(Object, Method, Object...) line: 49       
$Proxy3.findByPrimaryKey(SetupPK) line: not available   
LookupMemTest.main(String[]) line: 16   
{code}
Trace of second spot where liveRegistryMap is populated
{code:java}
EJBInvocationHandler.registerHandler(Object, EJBInvocationHandler) line: 205    
EntityEJBHomeHandler.findX(Method, Object[], Object) line: 59   
EntityEJBHomeHandler(EJBHomeHandler)._invoke(Object, Method, Object[]) line: 
136        
EntityEJBHomeHandler(EJBInvocationHandler).invoke(Object, Method, Object...) 
line: 136  
Jdk13InvocationHandler.invoke(Object, Method, Object...) line: 49       
$Proxy3.findByPrimaryKey(SetupPK) line: not available   
LookupMemTest.main(String[]) line: 16   
{code}
EntityEJBHomeHandler.findX code
{code:java}
57: handler = EJBObjectHandler.createEJBObjectHandler(executor, ejb, server, 
client, primKey, authenticationInfo);
58: handler.setEJBHomeProxy((EJBHomeProxy) proxy);
59: registerHandler(ejb.deploymentID + ":" + primKey, handler);
{code}
EJBInvocationHandler: code
{code:java}
    protected static void registerHandler(final Object key, final 
EJBInvocationHandler handler) {
        Set<WeakReference<EJBInvocationHandler>> set = 
liveHandleRegistry.get(key);

        if (set == null) {
            set = new HashSet<WeakReference<EJBInvocationHandler>>();
            final Set<WeakReference<EJBInvocationHandler>> current = 
liveHandleRegistry.putIfAbsent(key, set);
            // someone else added the set
            if (current != null) {
                set = current;
            }
        }

        final ReentrantLock l = lock;
        l.lock();

        try {
            set.add(new WeakReference<EJBInvocationHandler>(handler));
        } finally {
            l.unlock();
        }
    }
{code}

> Remote EJB2 BMP Memory Leak
> ---------------------------
>
>                 Key: TOMEE-4120
>                 URL: https://issues.apache.org/jira/browse/TOMEE-4120
>             Project: TomEE
>          Issue Type: Bug
>          Components: TomEE Core Server
>    Affects Versions: 8.0.13
>         Environment: I am using apache-tomee-plus-8.0.6 under windows 10 and 
> jdk 8.
>            Reporter: Thomas Lien
>            Priority: Major
>         Attachments: mem1.png, mem2.png, mem3.png
>
>
> I'm seeing a significant memory leak when loading ejb2 bmps remotely. Not 
> including the server side code because it doesn't appear to be particularly 
> relevant since I've found that any ejb2 bmp does the same thing and the leak 
> happens on the client side. The problem eventually causes our client 
> application to crash with an out of memory error.
> Below is a simple main function I made to demonstrate. If I run this program 
> below using a single ejb2 findByPrimaryKey call, memory will grow rapidly. I 
> traced it down using the Eclipse Memory Profiler to the 
> org.apache.openejb.client.EJBInvocationHandler class retaining memory in a 
> ConcurrentHashMap field called liveHandleRegistry. I can see it has my 
> SetupHome object as a key and a HashSet as values. Attaching screenshots of 
> the eclipse memory profiler as it continues to grow over a few minutes as the 
> program runs.
> {code:java}
> import javax.naming.InitialContext;
> import alliancetechnical.sm4.ejb.SetupHome;
> import alliancetechnical.sm4.ejb.SetupPK;
> public class LookupMemTest {
>     public static void main(String[] args) throws Exception {
>         System.setProperty("java.naming.factory.initial", 
> "org.apache.openejb.client.RemoteInitialContextFactory");
>         System.setProperty("java.naming.provider.url", 
> "http://127.0.0.1:8080/tomee/ejb";);
>         InitialContext ctx = new InitialContext();
>         SetupHome setupHome = (SetupHome)ctx.lookup("SetupHome");
>         while (!Thread.currentThread().isInterrupted()) {
>             setupHome.findByPrimaryKey(new SetupPK(1));
>             Thread.sleep(5);
>         }
>     }
> }
> {code}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to