2 Replies Latest reply on May 28, 2009 8:54 AM by Alessio Soldano

    Memory leak with Provider<Source> webservice implementation

    Sergey Graschenko Newbie

      Hi,

      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.