users@jersey.java.net

Re: [Jersey] memory leak with CDI ?

From: satish gopalakrishnan <satish99_at_gmail.com>
Date: Sat, 24 Jul 2010 16:22:29 -0400

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> 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
> > 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
>>
>>
>