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.