Memory leak with Provider<Source> webservice implementation
sintetik7 May 21, 2009 6:13 AMHi,
I have a problem running my app that implements webservice using Provider api. After ~4hrs of mild load AS goes out of memory.
I'm using JBoss 5.0.1 with sun jdk 1.6.0_14. Configuration is
-Xms256m -Xmx1024m -XX:MaxPermSize=256m -Dorg.jboss.resolver.warning=true -XX:+UseConcMarkSweepGC -Dsun.rmi.dgc.client.gcInterval=1800000 -Dsun.rmi.dgc.server.gcInterval=1800000
My endpoints defined as follows:
@WebServiceProvider(serviceName = "StorageService", portName = "External", wsdlLocation = "WEB-INF/wsdl/storage.wsdl") @BindingType(value = HTTPBinding.HTTP_BINDING) @ServiceMode(value = Service.Mode.PAYLOAD) public class StorageServiceExternalProvider extends AbstractServiceProvider implements Provider<Source> { @Resource(type = Object.class) protected WebServiceContext wsContext; public Source invoke(Source req) { MessageContext mc = wsContext.getMessageContext(); String path = ((String) mc.get(MessageContext.PATH_INFO)).substring(1); return invoke(path, req); } protected String getJndiNameSLSB() { return "StorageExternalSarco/local"; } }
public abstract class AbstractServiceProvider { private static Logger log = Logger.getLogger(AbstractServiceProvider.class); protected abstract String getJndiNameSLSB(); public Source invoke(String path, Source req) { JAXBContext jc = null; Object local; Method[] localMethods; try { InitialContext ic = new InitialContext(); local = ic.lookup(getJndiNameSLSB()); ic.close(); localMethods = local.getClass().getMethods(); jc = StorageJAXBContext.getContext(); } catch (Throwable t) { log.error("Unable to initialize", t); return new DOMSource(); } Reader decoded; Object in = null; try { decoded = new StringReader(URLDecoder.decode(req.toString(), "utf8")); in = jc.createUnmarshaller().unmarshal(decoded); if (in instanceof JAXBElement<?>) in = ((JAXBElement<?>)in).getValue(); for (Method m : localMethods) if (m.getName().equals(path)) { Object result = m.invoke(local, in); Class<?> retType = m.getReturnType(); if (retType == Void.TYPE) return new DOMSource(); else return new JAXBSource(jc, result); } throw new Exception("Accessing invalid path: " + path); } catch (Throwable e) { log.error("Error processing invocation for path: " + path + ", input type is: " + (in == null ? "NULL" : in.getClass()), e); return new DOMSource(); } }
web.xml:
<servlet> <servlet-name>StorageServiceExternalProvider</servlet-name> <servlet-class>com.photoholding.storage.StorageServiceExternalProvider</servlet-class> </servlet> <servlet-mapping> <servlet-name>StorageServiceExternalProvider</servlet-name> <url-pattern>/External/*</url-pattern> </servlet-mapping>
I tried to do jmap profiling and it shows lots of B[ and C[ objects growing with time. Looks like "Provider" instance is never released and GC skips it - size of the OldGen grows until GC can't handle it.
Any help is appreciated.