gavenkoa
gavenkoa

Reputation: 48813

Reason for PermGen OutOfMemoryError when "No GC root found"?

I fix 3 different PermGen OutOfMemoryError issues in webapp and it survives any number of redeploys (I don't try larger then 30) in restricted -XX:MaxPermSize=66m. Running application takes ~55 MB of PermGen.

Main reason to fix memory leaks is to practice and to make development environment more pleasant - with <Context reloadable="true"> after compilation my webapp have been redeployed after 3 sec!

Just now I have found error in catalina.out:

Dec 26, 2015 5:28:09 PM org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor run
SEVERE: Unexpected death of background thread ContainerBackgroundProcessor[StandardEngine[Catalina]]
java.lang.OutOfMemoryError: PermGen space

Exception in thread "ContainerBackgroundProcessor[StandardEngine[Catalina]]" 
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "ContainerBackgroundProcessor[StandardEngine[Catalina]]"

As usual I run visualvm and run OQL:

select unique(map(heap.objects('java.lang.ClassLoader'), 'classof(it)'))

and review org.apache.catalina.loader.WebappClassLoader instances. What I actually do can be described by OQL:

filter(heap.objects('org.apache.catalina.loader.WebappClassLoader'),
                    'it.state.name.toString() == "DESTROYED"')

That one instance doesn't freed PermGen memory. But when I invoked find nearest GC root I get No GC root found.

What is the reason for PermGen OutOfMemoryError when No GC root found?

Is that possible that reason for OutOfMemoryError is processing application requests during redeploy?

I make especially low PermGen to force GC in PermGen during application redeploy, because PermGen cleaned only on memory pressure - I decide to monitor if OutOfMemoryError still effects my app.

Upvotes: 0

Views: 3342

Answers (1)

Mattias Jiderhamn
Mattias Jiderhamn

Reputation: 2093

There are a couple of things worth looking at.

  1. Do you have sufficient PermGen to hold at least 2 instances of your application at the same time? I believe sometimes it takes the Garbage Collector multiple passes to remove all references, so there needs to be some "margin" for one instance being released for GC and another being loaded.
  2. Try switching to another Garbage Collector. I have seen situations I can only explain with bugs in the GC and Parallell, CMS and G1 behaves differently in those situations.
  3. In case you want to try out an alternative method for finding the GC root path, you can have a look at this blog series of mine or Arit.
  4. You may also want to see if the problem is resolved by adding my ClassLoader Leak Prevention Library to your app. In case it is, watch the logs for the potential reasons.

Upvotes: 1

Related Questions