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

Reply via email to