java.lang.OutOfMemoryError: PermGen space
. It usually occurs after restarting the web application inside the server without restarting the server itself. Restarting the web application without restarting the server may be necessary during the development process, in order not to wait for the server to start too much time. If you have multiple web applications delayed, restarting the entire server can be much longer than restarting a single web application. Or the entire server simply cannot be restarted, since other web applications are used. The first solution that comes to mind is to increase the maximum amount of PermGen memory available to the JVM (you can do this with the -XX:MaxPermSize
), but this will only delay the fall, after a few restarts you will again get OutOfMemoryError
. It would be nice to be able to restart and redistribute the web application on a running server as many times as you like. How to overcome PermGen, and will further discussion.OutOfMemoryError
.-XX:+CMSClassUnloadingEnabled
, -XX:+CMSPermGenSweepingEnabled
, -XX:+UseConcMarkSweepGC
. I didn’t dig deep and look for official documentation, but through trial and error I determined that for Java 7 and Tomcat 7 it is necessary and sufficient to add the JVM option -XX:+UseConcMarkSweepGC
. This option will change the garbage collection algorithm, if you are not sure that your application will not work worse because of this, then look for documentation and comparisons of different garbage collection algorithms to determine whether this option is worth using or not. You may need to enable this option to get rid of problems with PermGen. If not, then you most likely have a memory leak, what to do with it - read on.java.lang.Class
class, and each class stores a reference to the class loader that loaded this class, and each class loader stores references to all the classes it has loaded. It turns out that only one link from the outside to the web application object pulls along all the classes of the web application and the inability to collect them by the garbage collector.ThreadLocal
variable, which assigns an object from a web application to a stream from a common pool. In this case, the thread stores an object reference. The stream from the common pool cannot be destroyed, the object cannot be destroyed, it means that the whole class loader with all classes cannot be destroyed.JreMemoryLeakPreventionListener
- a solution for well-known possible variants of memory leaks, configured in server.xml
( details ). Perhaps turning on any options on this listener will help get rid of memory leaks.SEVERE: The web application [/drp] appears to have started a thread named [AWT-Windows] but has failed to stop it. This is very likely to create a memory leak.
SEVERE: The web application [/drp] created a ThreadLocal with key of type [org.apache.log4j.helpers.ThreadLocalMap] (value [org.apache.log4j.helpers.ThreadLocalMap@7dc1e95f]) and a value of type [java.util.Hashtable] (value [{session=*2CBFB7}]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
-XX:MaxPermSize=100M
) so that after two or three restarts of the web application, the occupied memory reaches 100 %, and either a cleanup occurred, or an OutOfMemoryError
fell if there were still leaks.SEVERE: The web application [/drp] appears to have started a thread named [AWT-Windows] but has failed to stop it. This is very likely to create a memory leak.
AWT-Windows
thread, therefore, its contextClassLoader
turned out to be a class loader of the web application, and the garbage collector cannot collect it. Here we can track using breakpoint with the condition on the name of the thread, who created this stream, and, having rummaged in the source code, find what opportunities it can stop, for example, set a flag or call some method, for example Thread#interrupt()
. These steps will need to be performed when the web application is stopped.JreMemoryLeakPreventionListener
, about which we learned above, can do something with this thread? We go to the documentation and see that the listener actually has the AWTThreadProtection
parameter, which for some reason is false by default. We put it in true in server.xml and make sure that Tomcat does not issue such a message.AWT-Windows
thread was created due to captcha generation on the server using the image manipulation classes from the JDK.SEVERE: The web application [/drp] created a ThreadLocal with key of type [org.apache.log4j.helpers.ThreadLocalMap] (value [org.apache.log4j.helpers.ThreadLocalMap@7dc1e95f]) and a value of type [java.util.Hashtable] (value [{session=*2CBFB7}]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
ThreadLocal
variable of the class ThreadLocalMap
some value and did not remove it. We are looking for where the ThreadLocalMap
class is used, we find org.apache.log4j.MDC
, and this class is already directly used in our web application for logging additional information. We see that the put
method of the MDC
class is called, and the remove
method is not called. It seems that calling remove
for each put
in the right place should help. We fix, check - it works!OutOfMemoryError: PermGen space
, at least in my practice this was so.select x from org.apache.catalina.loader.WebappClassLoader x
started
field. The old started
will be false
.this
and select "Show Nearest GC Root".contextClassloader
. Click on it with the right mouse button and select “Show Instance”.AWT-Windows
. We found the same problem that Tomcat wrote to us about using VisualVM only. How to solve it you already know.Source: https://habr.com/ru/post/222443/
All Articles