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

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

Elevating the severity because it is causing app crashes and there is really no 
workaround.

A code change I see that could be done to fix the problem would be to loop 
through the WeakReference Set every time a new one is added and remove any 
WeakReferences with the null referent. The new EJBInvocationHandler code would 
look like this.

{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 {
            // UPDATE HERE: loop through and remove old references that have 
been garbage collected
            for (Iterator<WeakReference<EJBInvocationHandler>> i = 
set.iterator(); i.hasNext(); ) {
                if (i.next().get() == null)
                        i.remove();
            }
            // END OF UPDATE
            set.add(new WeakReference<EJBInvocationHandler>(handler));
        } finally {
            l.unlock();
        }
    }

{code}


Also removing registerHandler in the EntityEJBObjectHandler constructor is 
probably a good idea since this causes it to be double registered in the map.

> 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.13 under windows 10 and 
> jdk 8.
>            Reporter: Thomas Lien
>            Priority: Critical
>         Attachments: mem1.png, mem2.png, mem3.png, memoryleak.png, 
> test.ear.zip, testjar-src.zip
>
>
> I'm seeing a significant memory leak when loading ejb2 bmps remotely. I've 
> found that any ejb2 bmp finder function has a leak on 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 "BMPTestHome:1" 
> as the key and a HashSet of WeakReferences as values. Attaching screenshot of 
> the eclipse memory profiler which continues to grow the longer the program 
> runs (memoryleak.png).
> {code:java}
> package test;
> import javax.naming.InitialContext;
> 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();
>               BMPTestHome bmpTestHome = 
> (BMPTestHome)ctx.lookup("BMPTestHome");
>               while (!Thread.currentThread().isInterrupted()) {
>                       bmpTestHome.findByPrimaryKey(new BMPTestPK(1));
>                       Thread.sleep(5);
>               }
>       }
> }
> {code}



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

Reply via email to