voyent
2 MemoryLeaks in ResourceDispatcher/PathDispatcherServer  XML
Forum Index -> Contributor's Corner
Author Message
slite

Joined: 22/Feb/2008 00:00:00
Messages: 58
Offline


Hi there,

We experienced some performance issues due to full heap memory so i started to profile and take regular heap snapshots and tried tracking down the cause by diffing the results.

Problems start after some days with heavy usage, heap dumps show a _huge_ number of instances of the following classes:
com.icesoft.faces.component.outputresource.RegisteredResource
com.icesoft.faces.webapp.http.core.ResourceDispatcher$ResourceServer$1
com.icesoft.faces.webapp.http.core.ResourceDispatcher$ResourceServer

As a side info: We have a bunch of outputResources in our app which are always visible and change hashcode very frequently.

What i found out is the following: (line numbers refer to current line numbers on HEAD at sventon.icefaces.org)

MainSessionBoundServlet.java:
Code:
77:         final ResourceDispatcher resourceDispatcher = new ResourceDispatcher(ResourcePrefix, mimeTypeMatcher, sessionMonitor, configuration);
 


ResourceDispatcher is created once in the mainsession servlet and passed down through some layers until it reaches...

BridgeFacesContext.java:
Code:
167:         this.resourceDispatcher = resourceDispatcher;
 


... at the constructor and is referenced there. So if i got everything right we just have one Instance of the ResourceDispatcher and every FacesContext holds a reference to it.

OutputResource.java:
Code:
90:                 path = ((ResourceRegistry) FacesContext.getCurrentInstance()).registerResource(
 91:                         r).getRawPath();
 


Every OutputResource component registers its resources there.

ResourceDispatcher.java:
Code:
87:             registered.add(name);
 88:             dispatcher.dispatchOn(".*" + name.replaceAll("\\/", "\\/") + dispatchFilename + "$", new ResourceServer(resource));


Every ResourceName gets added to the "registered" ArrayList and the ArrayList only gets cleared in the shutdown() method. (Which is called on context shutdown if i got everything right). Memory Leak 1

PathDispatcherServer.java:
Code:
 32:     public void dispatchOn(String pathExpression, final Server toServer) {
 33:         matchers.add(Pattern.compile(pathExpression));
 34:         servers.add(toServer);
 35:     }
 


For every Resource a expression gets added to "matchers" ArrayList, like before the ArrayList ony gets cleared in the shutdown() method. Same applies to "servers" ArrayList. Where servers List is the greate evil because toServer contains a pointer to the resource itself, so the resources also stay in memory. Memory Leak 2

I think this was left undiscovered for a long time as only heavy usage of OuputResources leads to a problem after some uptime of the application server.

We also have a Developer Support Contract, would be nice if this could be fixed asap. Please notify me if we should open a support ticket in addition to that detailed description.

Imho some garbage collection for old resources is needed there and maybe a contextparam to configure resource maximum age.
slite

Joined: 22/Feb/2008 00:00:00
Messages: 58
Offline


Another sidenote: We use our own Resource Implementation which again holds some references to session objects.

This might be the reason why this leads to problems pretty fast on our servers cause the garbage collector might not be able to destroy expired user sessions as well because of these pointers.
mircea.toma

Joined: 10/Feb/2005 00:00:00
Messages: 323
Offline


The current resource registration assumes that resources are needed during the entire session lifetime. For resources that are highly dynamic and change their content along the session lifetime the digest of the resource should not change and the caching related options should be used (expires-by and last-modified). Thus reflecting the change in the content of the resource.
....
As a side info: We have a bunch of outputResources in our app which are always visible and change hashcode very frequently. 

This seems to be an issue with the outputResource component. The component should not rely on the hashcode but on the digest (Resource.calculateDigest) when deciding on registering resources.
.....
I think this was left undiscovered for a long time as only heavy usage of OuputResources leads to a problem after some uptime of the application server. 

It looks like it. You might try using the ResourceRegistry directly to gain more control over how Resources are registered and also coupled with the strategy described at the beginning of my reply.
....
Imho some garbage collection for old resources is needed there and maybe a contextparam to configure resource maximum age. 

I don't think contextparam idea is feasible because you do not know until when the user will need a certain resource. Maximum age is the session timeout.

Here's where you can track the progress for the outputResource issue: http://jira.icefaces.org/browse/ICE-5018
[Email]
slite

Joined: 22/Feb/2008 00:00:00
Messages: 58
Offline


This means resources are garbaged when the lifetime of a usersession ends?

Cause i couldn't find anything like that in the source, my impression was, that the ResourceDispatcher stuff holds all resources of all sessions in its ArrayLists and there is no point when resources expire. (Except shutdown() method which i thought is called only on applicationcontext shutdown)

Please could clarify to my if and at which time registered resources expire.

If resources expire when a user session expires the problem isn't as severe as we thought it was.

By further investigating our heap dumps we also found a memoryleak in our own code which had a much bigger impact on the memory footprint of our app. I will fix that tomorrow which should alleviate our memory problems a lot.

We will further investigate memory usage when our own leak is fixed and keep you informed.

best regards
daniel
 
Forum Index -> Contributor's Corner
Go to:   
Powered by JForum 2.1.7ice © JForum Team