users@jersey.java.net

[Jersey] Re: Memory leak with SystemDescriptor

From: Veit Guna <Veit.Guna_at_gmx.de>
Date: Thu, 30 Apr 2015 18:11:08 +0200

Hi Marek.
 
I would love to. But I can't attach any files to the issue.
 
Also I wanted to change the text/title, because it doesn't reflect the root problem. I realized it _after_ I saved the issue :(.
Maybe you can add the test project for me? And change the title to something like "@BeanParam injection behavior changed with 2.17"?
 
It's tracked here: https://java.net/jira/browse/JERSEY-2849
 
Thanks
Veit



 

Gesendet: Donnerstag, 30. April 2015 um 17:04 Uhr
Von: "Marek Potociar" <marek.potociar_at_oracle.com>
An: users_at_jersey.java.net
Betreff: [Jersey] Re: Memory leak with SystemDescriptor

Can you please open a Jira issue and attach the reproducer to the issue instead?
 
Cheers,
Marek


On 29 Apr 2015, at 18:09, Veit Guna <Veit.Guna_at_gmx.de> wrote: 
Hi Marek.
 
Please find attached a small testcase that shows the problem.
It's quite ugly (I reused it from an Apache CXF testcase), but should be enough for demonstration.

It's a maven project that includes a war. If you execute "mvn clean install", it will automatically
start a tomcat container via cargo, deploys the war, and execute the JerseyIT test.

The test itself simply invokes an endpoint (RepositoryEntryResourceImpl)
and sends an entryId to it (url: http://localhost:8080/test/api/repositories/0815/entries/0816[http://localhost:8080/test/api/repositories/0815/entries/0816]).

The endpoint reads from the injected PathContext the entryId and returns it to the testcase. It expects that
0816 is returned.

It should work with 2.16. If you change the version to 2.17 in the pom, it should fail with a null
returned from the endpoint.

If you take a look at the server log, the following is shown:

2.16:

Apr 29, 2015 5:54:55 PM test.PathContext postConstruct
INFO: hashCode: 556592017, repositoryId: 0815, entryId: null

Apr 29, 2015 5:54:55 PM test.PathContext postConstruct
INFO: hashCode: 29437898, repositoryId: 0815, entryId: 0816

Apr 29, 2015 5:54:55 PM test.RepositoryEntryResourceImpl getEntry
INFO: injected pathContext: hashCode: 29437898, repositoryId: 0815, entryId: 0816


Actually PathContext is created twice. Once for every endpoint. The 2nd instance
(for RepositoryEntryResourceImpl) now contains the correct entryId.

2.17:

Apr 29, 2015 5:58:28 PM test.PathContext postConstruct
INFO: hashCode: 1730327498, repositoryId: 0815, entryId: null

Apr 29, 2015 5:58:28 PM test.RepositoryEntryResourceImpl getEntry
INFO: injected pathContext: hashCode: 1730327498, repositoryId: 0815, entryId: null


Here, PathContext is only created once. Same instance is injected only once
into the different endpoints. Also entryId is null.


I hope that helps tracking down the problem.

Thanks
Veit
 
 
 

Gesendet: Mittwoch, 29. April 2015 um 13:33 Uhr
Von: "Marek Potociar" <marek.potociar_at_oracle.com[marek.potociar_at_oracle.com]>
An: users_at_jersey.java.net[users_at_jersey.java.net]
Betreff: [Jersey] Re: Memory leak with SystemDescriptor
Hi Veit,

It would be good if you could provide a concrete reproducer test for your problem. I’m not able to infer the necessary details about your use case from your description. Hard to look into the issue without having the full context.

Marek
 On 29 Apr 2015, at 12:23, Veit Guna <Veit.Guna_at_gmx.de[Veit.Guna_at_gmx.de]> wrote:

Hi.

I've digged deeper into the rabbit hole and came to the same results as reported here:

https://java.net/jira/browse/JERSEY-2800[https://java.net/jira/browse/JERSEY-2800]

It also got filled up with @BeanParams classes.

Then I switched to 2.17 and found out, that my @BeanParam class (PathContext) is missing some functionality.
It looks like that:

public class PathContext {

@PathParam(TenantResource.TENANT_ID_PATH_PARAM)
private String tenantId;
@PathParam(AccountResource.ACCOUNT_ID_PATH_PARAM)
private String accountId;
@PathParam(RepositoryResource.REPOSITORY_ID_PATH_PARAM)
private String repositoryId;
@PathParam(RepositoryEntryResource.REPOSITORY_ENTRY_ID_PATH_PARAM)
private String repositoryEntryId;
....

With 2.16 and prior, Calling a URL like this:

http://localhost:8080/something/api/1/tenants/b38c7e6b-f17f-45bf-a746-65b40f95d845/repositories/1ee83a90-6e2f-435c-ac6a-ece0f5106671/entries

Resulted into filled tenantId and repositoryId.

Now, only tenantId is filled - although repositoryId should also be accessible.
I can also confirm, that now only one instance of PathContext is created (using @PostConstruct).
With 2.16 it were 3: 1st with only tenantId set, the other 2 instances had repositoryId correctly set.

PathContext is injected into different resources as field member. Resources are accessed via Subresourcelocators.
So I'm wondering if the fix from JERSEY-2800 maybe broke some other stuff?

I would expect, if I inject the PathContext anywhere, it should parse the complete URL for the specified @PathParams.
This didn't seem to happen anymore.

Can someone confirm this?

Thanks!
Veit



Gesendet: Mittwoch, 29. April 2015 um 08:48 Uhr
Von: "Veit Guna" <Veit.Guna_at_gmx.de>
An: users_at_jersey.java.net
Betreff: [Jersey] Memory leak with SystemDescriptor
Hi.

We're using Jersey 2.16 with JDK 1.7.0_55-b13 64 bit and Tomcat 7.0.21 under Windows 7 to build a REST api.
Now, we're facing a problem with memory usage during load. We've created a TestNG testcase method, that
performs CRUD operations 10 times in a loop. That method is invoked 1000 times by 50 concurrent threads.

After approx. 30 minutes, the server gets slower and slower until it gets an OutOfMemoryException. We
created a ThreadDump with jvisualvm and used Eclipse Memory Analyzer to get to the root problem.

It seems that hk2's SystemDescriptor is eating memory like a boss :). Here's the output of the analyzer:

170.088 instances of "org.jvnet.hk2.internal.SystemDescriptor",
loaded by "org.apache.catalina.loader.WebappClassLoader @ 0xc026bd80"
occupy 625.581.408 (92,47%) bytes.
These instances are referenced from one instance of "org.jvnet.hk2.internal.ServiceLocatorImpl",
loaded by "org.apache.catalina.loader.WebappClassLoader @ 0xc026bd80"

We already found an old JIRA ticket regarding a SystemDescriptor memory leak:

https://java.net/jira/browse/HK2-205[https://java.net/jira/browse/HK2-205][https://java.net/jira/browse/HK2-205[https://java.net/jira/browse/HK2-205]]

that was fixed in 2.3.0.

So we switched to the latest hk2 version, 2.4.0-b16. But without any effect.

We're wondering what SystemDescriptor is used for and why it is eating so much memory.

Does anyone have deeper insights?

Thanks!
Veit <test.zip>