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