[
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)