users@jersey.java.net

RE: [Jersey] memory leak with CDI ?

From: Herak Sen <HSen_at_vertrax.com>
Date: Mon, 26 Jul 2010 09:09:59 -0400

I think many of us are facing the same issue and problem seems to be coming from WELD.
It has been already reported and being worked on and I am hoping they resolve it soon.
See

1) https://glassfish.dev.java.net/issues/show_bug.cgi?id=12368

2) https://jira.jboss.org/browse/WELD-453

3) https://jira.jboss.org/browse/WELD-476

Herak




From: satish gopalakrishnan [mailto:satish99_at_gmail.com]
Sent: Saturday, July 24, 2010 4:22 PM
To: users_at_jersey.dev.java.net
Subject: Re: [Jersey] memory leak with CDI ?

Thanks for the reply. The HelloService is actually an empty class. It doesn't have any qualifiers and no explicit scope defined. I am providing all the code at the end of the email - minus all the imports etc. Thats why this is so puzzling to me - just about 20 lines of total code, and I am able to reproduce the issue quite easily. I understand that a new instance of the bean / HelloService gets created on each request, but it should also be cleaned up at the end of the request - which is happening, since the heap analysis doesn't show these beans or the resource classes as the leak suspects, but something within weld as I mentioned in my previous email.

I hope there's a simple explanation for this.

HelloService and HelloServiceImpl
--------------------------------------------------

public interface HelloService {
}

public class HelloServiceImpl implements HelloService {
}
Resource Class
-----------------------

import javax.enterprise.context.RequestScoped;
@Path("/hello")
@RequestScoped
public class HelloWorldResource {

    @Inject
    HelloService helloService;
    @GET
    @Produces("text/xml")

    public String helloWorldTest() {
        helloService.toString();
        System.out.println("basic request" + helloService.hashCode() + helloService.getClass().getName());
        return "abc";
   }
}



web.xml
----------------

    <servlet>
        <servlet-name>rest</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>rest</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

On Sat, Jul 24, 2010 at 11:44 AM, John Ament <my.reprive_at_gmail.com<mailto:my.reprive_at_gmail.com>> wrote:
Satish,

Can you provide the original implementation of what HelloService was doing? Eg. the qualifiers in play, scopes, etc. There's definitely some quirks with regards to CDI. For example, a coworker of mine was able to generate a linux error max number of files open using CDI. How? She created a dependent bean that had a dependent injection point that read from a file. There was a bug in the reading that resulted in the file never being closed and repeatedly opened. However, she bound the top level bean to a name. With the behavior of dependent plus the behavior of named, a single page would end up creating 20+ instances of that bean by itself. Just watch out with request scoped - request scoped beans get created regardless of whether they are used or not.

John

On Sat, Jul 24, 2010 at 9:10 AM, satish gopalakrishnan <satish99_at_gmail.com<mailto:satish99_at_gmail.com>> wrote:
Thanks for the response. I did annotate my resource with @Singleton (javax.inject) and after about 6 hours or so, memory usage does seem to be stable. With the @Request scope, I would have already seen the memory usage go up by now.

With @Request scope, almost after every full GC the tenured pool usage keeps increasing and in a couple or days I would run out of 512 MB of heap space with an OOM error.

So to summarize, these are the observations so far

1. With @Request scope and using @inject, there is a memory leak.
2. Using just a servlet while using @inject, there is no memory leak ( basically not using REST Resource )

3. With @Singleton scope, there doesn't seem to be any leak based on early results.

I am seeing that the same instance of the HelloService is being used on every method invocation - which I guess is expected since the Resource is Singleton scope , the injected HelloService has the same scope.

So based on these observations, any ideas on what may be going on ? A few days back, I did do a heap dump analysis with ecipse mat , and just the basic "leak suspects" gives me the following

One instance of "org.jboss.weld.manager.BeanManagerImpl" loaded by "org.apache.felix.framework.ModuleImpl$ModuleClassLoader @ 0x93fd5ad8" occupies 233,469,192 (79.61%) bytes. The memory is accumulated in one instance of "com.google.common.collect.CustomConcurrentHashMap$Impl$Segment[]" loaded by "org.apache.felix.framework.ModuleImpl$ModuleClassLoader @ 0x93fd5ad8

I know this points to something in WELD, but when I use @inject in other applications without using jersey, I haven't come across issue, so I am thinking maybe something involving jersey is going on. Quite possible that this is weld related too.

Thanks again !






> To get the simple stuff out of the way - until a GC actually runs, you should see the amount of memory in use increase - your JAX-RS resources (explicitly, or in general by default) are created on each call, and only used for that one call. So > you would expect memory use to increase, until GC cleans up.

> You could annotate your resource to be a singleton, instead, to see if memory use remains stable ...

> Moises

On Jul 23, 2010, at 10:45 PM, satish gopalakrishnan wrote:

> Hi,
> I am using glassfish v 3.01. I have the simplest of applications - a hello world resource and a helloService which is empty. When I access it repeatedly using just wget, after a while I see that the memory usage keeps increasing - basically a memory leak. Here is the code
>
>
> @Path("/hello")
> @RequestScoped
> public class HelloWorldResource {
>
> @Inject
> HelloService helloService;
> public String helloWorldTest(){
> helloService.toString();
> return "xyz"
> }
> }
>
> Am I doing something wrong here ? This is the simplest possible application with CDI and jersey - so somewhat surprised that this can have a memory leak. I tried @managedBean as well. Same result.
>
> My web.xml looks like this
>
> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
> <init-param>
> <param-name>javax.ws.rs.Application</param-name>
> <param-value>mtest.HelloApplication</param-value>
> </init-param>
> </servlet>
>
>
> Any help / insights would be greatly appreciated
>
> thanks