I'm looking at TUSCANY-3173 and and the memory leak appears to relate
to some thread local storage we use relating to service proxies. In
the start() method of the JSONRPCServiceBindingProvider is the
following code...
public void start() {
// Set default databinding to json
serviceContract.getInterface().resetDataBinding(JSONDataBinding.NAME);
// Determine the service business interface
Class<?> serviceInterface =
getTargetJavaClass(serviceContract.getInterface());
// Create a Java proxy to the target service
** Object proxy =
component.getComponentContext().createSelfReference(serviceInterface,
service).getService();
// Create and register a Servlet for this service
JSONRPCServiceServlet serviceServlet =
new JSONRPCServiceServlet(messageFactory, binding,
service, serviceContract, serviceInterface, proxy);
The line I've marked with ** create and SCA service proxy and then
passed it into the servlet. Under the covers this proxy object finds
it's way into the JSONRPC library and is used to identify available
methods for the service etc.
In the case of the memory leak is happening a typical reference chain
for the WebAppClassloader is..
--> com.ctc.wstx.api.wstxinputproperties$parsingm...@0x3252888 (8 bytes) (??:)
--> class com.ctc.wstx.api.WstxInputProperties$ParsingMode (84 bytes) (??:)
--> org.apache.catalina.loader.webappclassloa...@0x320abe8 (152 bytes)
(field system:)
--> sun.misc.launcher$appclassloa...@0x2f17f00 (63 bytes) (field classes:)
--> java.util.vec...@0x2f21450 (24 bytes) (field elementData:)
--> [Ljava.lang.Object;@0x2f289c8 (88 bytes) (Element 0 of
[Ljava.lang.Object;@0x2f289c8:)
--> class org.apache.catalina.startup.Bootstrap (84 bytes) (static
field daemon:)
--> org.apache.catalina.startup.bootst...@0x2f17dd0 (24 bytes) (field
catalinaDaemon:)
--> org.apache.catalina.startup.catal...@0x2f33cd8 (101 bytes) (field
shutdownHook:)
--> org.apache.catalina.startup.catalina$catalinashutdownh...@0x3140790
(108 bytes) (field group:)
--> java.lang.threadgr...@0x2f17a10 (43 bytes) (field threads:)
--> [Ljava.lang.Thread;@0x319fa48 (72 bytes) (Element 10 of
[Ljava.lang.Thread;@0x319fa48:)
--> java.lang.thr...@0x31c9700 (104 bytes) (field threadLocals:)
--> java.lang.threadlocal$threadlocal...@0x31ce738 (20 bytes) (field table:)
--> [Ljava.lang.ThreadLocal$ThreadLocalMap$Entry;@0x3313318 (136
bytes) (Element 11 of
[Ljava.lang.ThreadLocal$ThreadLocalMap$Entry;@0x3313318:)
--> java.lang.threadlocal$threadlocalmap$en...@0x33132d8 (28 bytes)
(field value:)
--> org.apache.tuscany.sca.core.invocation.messagei...@0x33139a0 (37
bytes) (??:)
--> class org.apache.tuscany.sca.core.invocation.MessageImpl (84 bytes) (??:)
--> org.apache.catalina.loader.webappclassloa...@0x32aad98 (152 bytes)
The following stack, from proxy creation, is therefore of interest (I
was just using the store node to generate this as I know it uses
JSONRPC)...
Thread [main] (Suspended (breakpoint at line 46 in MessageImpl))
MessageImpl.<init>() line: 46
ThreadMessageContext$1.initialValue() line: 34
ThreadMessageContext$1.initialValue() line: 31
ThreadMessageContext$1(ThreadLocal<T>).setInitialValue() line: 141
ThreadMessageContext$1(ThreadLocal<T>).get() line: 131
ThreadMessageContext.getMessageContext() line: 70
ComponentContextHelper.getCurrentComponent() line: 264
ComponentContextHelper.getCurrentCompositeActivator() line: 277
ServiceReferenceImpl<B>(CallableReferenceImpl<B>).resolve() line: 374
ServiceReferenceImpl<B>(CallableReferenceImpl<B>).getService() line:
209
JSONRPCServiceBindingProvider.start() line: 99
CompositeActivatorImpl$3.run() line: 630
AccessController.doPrivileged(PrivilegedAction<T>) line: not
available [native method]
CompositeActivatorImpl.start(Component) line: 628
CompositeActivatorImpl.start(Composite) line: 560
NodeImpl.start() line: 716
NodeImplementationLauncherBootstrap$NodeFacade.start() line: 56
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
available [native method]
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: 597
NodeLauncher.main(String[]) line: 139
LaunchStoreNode.main(String[]) line: 26
To save myself a lot of time working out what is going on can someone
explain what the ThreadMessageContext is doing here and why there is a
static context in that class.
When I comment out line ** and pass null into the servlet I don't get
the memory leak.
Regards
Simon