Dealing with "java.lang.OutOfMemoryError: PermGen space" error
Solution 1
The solution was to add these flags to JVM command line when Tomcat is started:
-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled
You can do that by shutting down the tomcat service, then going into the Tomcat/bin directory and running tomcat6w.exe. Under the "Java" tab, add the arguments to the "Java Options" box. Click "OK" and then restart the service.
If you get an error the specified service does not exist as an installed service you should run:
tomcat6w //ES//servicename
where servicename is the name of the server as viewed in services.msc
Source: orx's comment on Eric's Agile Answers.
Solution 2
You better try -XX:MaxPermSize=128M
rather than -XX:MaxPermGen=128M
.
I can not tell the precise use of this memory pool, but it have to do with the number of classes loaded into the JVM. (Thus enabling class unloading for tomcat can resolve the problem.) If your applications generates and compiles classes on the run it is more likely to need a memory pool bigger than the default.
Solution 3
App server PermGen errors that happen after multiple deployments are most likely caused by references held by the container into your old apps' classloaders. For example, using a custom log level class will cause references to be held by the app server's classloader. You can detect these inter-classloader leaks by using modern (JDK6+) JVM analysis tools such as jmap and jhat to look at which classes continue to be held in your app, and redesigning or eliminating their use. Usual suspects are databases, loggers, and other base-framework-level libraries.
See Classloader leaks: the dreaded "java.lang.OutOfMemoryError: PermGen space" exception, and especially its followup post.
Solution 4
Common mistakes people make is thinking that heap space and permgen space are same, which is not at all true. You could have lot of space remaining in the heap but still can run out of memory in permgen.
Common causes of OutofMemory in PermGen is ClassLoader. Whenever a class is loaded into JVM, all its meta data, along with Classloader, is kept on PermGen area and they will be garbage collected when the Classloader which loaded them is ready for garbage collection. In Case Classloader has a memory leak than all classes loaded by it will remain in memory and cause permGen outofmemory once you repeat it a couple of times. The classical example is Java.lang.OutOfMemoryError:PermGen Space in Tomcat.
Now there are two ways to solve this:
1. Find the cause of Memory Leak or if there is any memory leak.
2. Increase size of PermGen Space by using JVM param -XX:MaxPermSize
and -XX:PermSize
.
You can also check 2 Solution of Java.lang.OutOfMemoryError in Java for more details.
Solution 5
Use the command line parameter -XX:MaxPermSize=128m
for a Sun JVM (obviously substituting 128 for whatever size you need).
Chris
My languages, ordered by fluency: English, SQL, Ruby, Java, Mandarin Chinese, Python, Javascript, HTML, CSS.
Updated on March 14, 2022Comments
-
Chris about 2 years
Recently I ran into this error in my web application:
java.lang.OutOfMemoryError: PermGen space
It's a typical Hibernate/JPA + IceFaces/JSF application running on Tomcat 6 and JDK 1.6. Apparently this can occur after redeploying an application a few times.
What causes it and what can be done to avoid it? How do I fix the problem?
-
Eran Medan over 14 yearsI have fought this for hours, but I have no good news. See my related question: stackoverflow.com/questions/1996088/… You may still have a memory leak, e.g. classes are not garbage collected because your WebAppClassLoader is not garbage collected (it has an external reference that is not cleared). increasing the PermGen will only delay the OutOfMemoryError, and allowing class garbage collection is a precondition, but will not garbage collect classes if their class loader still has references to it.
-
masT over 10 yearsI got this error at adding display taglib. Removing so also solved the error. Why so?
-
matbrgz about 10 yearsAnd how did you run into it?
-
Rytek about 10 yearsuse JDK 1.8 :þ welcome to the MetaSpace
-
MacGyver about 7 yearsIf using Windows, follow these instructions instead of trying to set the flags manually in the config files. This properly sets the values in the registry to be called by Tomcat during runtime. stackoverflow.com/questions/21104340/…
-
-
meerkatlookout over 15 yearsThe only issue is that you're just delaying the inevitable- at some point you'll run out of headroom there too. It's a great pragmatic solution, but it doesn't solve it permanently.
-
Matt over 15 yearssame thing occurs in Eclipse and any time you have lots of dynamic class loading. the classloaders aren't disposed of and live in the permanent generation for all eternity
-
Taylor Leese almost 15 yearsThe article below suggests -XX:+UseConcMarkSweepGC and -XX:MaxPermSize=128m as well. my.opera.com/karmazilla/blog/2007/03/13/…
-
Eldelshell over 13 years-XX:+CMSPermGenSweepingEnabled This option brings down performance. It makes each request take three times more time than usual on our systems. Use with care.
-
sami over 13 yearsworked for me - thanks - I am doing this on Ubuntu 10.10 with Tomcat6 - I created a new file: /usr/share/tomcat6/bin/setenv.sh and added the following line to that: JAVA_OPTS="-Xms256m -Xmx512m -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled" - Restarted tomcat using: sudo /etc/init.d/tomcat6 start
-
knb almost 13 yearsOn tomcat 6.0.29 startup, from my catalina.out logfile: "Please use CMSClassUnloadingEnabled in place of CMSPermGenSweepingEnabled in the future"
-
stivlo almost 13 yearsOn a tomcat 5.5 on Ubuntu I've changed /etc/default/tomcat5.5 with the following JAVA_OPTS="-Djava.awt.headless=true -Xms128M -Xmx512M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=128m"
-
Dave over 12 yearsI was running out of PermGen when executing a particularly large Hudson job...this fixed it for me.
-
Péter Török over 12 years@TimHowland, it can be a permanent fix if the root cause is not classloader leakage, just too many classes/static data in your web app.
-
Deckard over 12 yearsHow to pass param
-XX:MaxPermSize and -XX:PermSize
?? I can't findcatalina.bat
. My tomcat version is5.5.26
. -
false9striker about 12 yearsI'm not able to open up tomcat6w.exe :( It says "The specified service does not exist as an installed service. Unable to open the service 'tomcat6' " . Could anyone help me on this?
-
Alex almost 12 years"argLine" is not recognized by maven-compiler-plugin 2.4. it only supports "compilerArgument", which gives error: <compilerArgument>-XX:MaxPermSize=256m</compilerArgument> [ERROR] Failure executing javac, but could not parse the error: javac: invalid flag: -XX:MaxPermSize=256m Usage: javac <options> <source files>
-
Rade_303 almost 12 yearsThis is only true solution to the problem, ableit in some cases too hard to implement.
-
Rade_303 almost 12 yearsActually, this will only postpone OOMError. See answer below started by anon with two links to frankkieviet blog.
-
Nikem almost 12 yearsFirst of all it would be great to explain what these flags really do. Just saying: "do that and enjoy" is not enough IMHO.
-
Nikem almost 12 yearsAnd second, if your application really leaks class loader, meaning that it leaves somewhere some object or class loaded by application's class loader even after undeployment, then these flags will not help. I have written blog post about this and other suggestions in this topic: plumbr.eu/blog/busting-permgen-myths
-
stracktracer almost 12 yearsWhile JRockit indeed has no PermGen, but this will not help in the long run. You'll get
java.lang.OutOfMemoryError: There is insufficient native memory
instead. -
gavenkoa over 11 yearsAnother very good source is people.apache.org/~markt/presentations/… (from Tomcat release manager!!).
-
Joachim Sauer about 11 yearsWhilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference.
-
igo about 11 yearsand if it still persist try
XX:MaxPermSize=1024m
:) -
Marko Vranjkovic almost 11 years-XX:+CMSClassUnloadingEnabled and -XX:+CMSPermGenSweepingEnabled are unusable in java 1.7, see link
-
Thomas almost 11 yearsand if it still persist try XX:MaxPermSize=2048m :)
-
Abdull over 10 years@lolotron, With Java
OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)
... runningjava -XX:+PrintFlagsFinal -version
... the returned list of flags includesCMSClassUnloadingEnabled
. -
qwerty about 10 yearsIf your compilation phase is running out of permgen set the <compilerArgument> on the maven-compiler-plugin. If the unit tests are running out of permgen set <argLine> in the maven-surefire-plugin
-
amos about 10 yearsThese options are explained here: oracle.com/technetwork/java/javase/tech/…
-
louisgab about 10 yearsgot the same issue as HDave when building jenkins/hudson from source.
-
Scot almost 10 yearsIf you don't want to include the driver in jre/lib/ext, you could probably get the same results by including the driver in your container startup classpath. java -cp /path/to/jdbc-mysql-driver.jar:/path/to/container/bootstrap.jar container.Start
-
reallynice almost 10 years@lolotron vulgarly trying to set it on tomcat 7 on "Java HotSpot(TM) Server VM (build 24.45-b08, mixed mode)", it works fine (no more OutOfMemory errors).
-
bluish almost 10 yearsHello, this answer has already been given: stackoverflow.com/a/22897121/505893. Please delete your answer, for clarity. If needed you could improve the answer I mentioned. Thanks ;)
-
Edwin Buck almost 10 years@bluish Thank you for pointing that out; however, that answer goes all sideways on talking about OutOfMemoryExceptions and leaking metadata. It also fails to mention the very important points of removing the PermGen option. In short, I'm not sure I would be improving the answer, but rather rewriting it. If it was just a quick touch-up, I would feel less hesitant, but it looks like it would be much more than a quick touch-up, and I'd hate to offend the original author. Still, this answer list is a dog's dinner of a mess, and perhaps killing my post would be best anyway.
-
Amit over 9 yearsHow to find the memory leaks of class loader ? Do you recommend any tool ?
-
Jonathan Airey over 9 yearsAnd if it STILL persists, rethink your application!! Or try XX:MaxPermSize=4096m :)
-
Jacek Pietal over 9 yearsyou can also try 8192m but thats a bit of overkill
-
leomeurer over 9 yearsGreat post of @faisalbhagat faisalbhagat.blogspot.com/2014/09/…
-
Senthil Kumar over 9 yearsTo know more about the flags - stackoverflow.com/questions/3334911/…
-
Joel Purra about 9 yearsOverkill indeed -- 640KB ought to be enough for anybody!
-
hdost about 9 yearsOption 2 is great, but just be warned that it should not be used in production environments. Typically best to keep it to development environments only. However PermGen is removed as of Java 8 openjdk.java.net/jeps/122
-
Barett about 9 years@amit for tool recommendations, see the community wiki answer on this question.
-
J Slick over 8 yearsA bit dated, like this thread, but here's documentation from Oracle: oracle.com/technetwork/java/…
-
Alex over 8 yearsI can do this on tomcat 7: add this line to setenv.sh [JAVA_OPTS="-Xms256m -Xmx512m -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled" ] ? will this work?
-
Kai Carver about 8 yearswhat worked for me on windows: created file
${tomcat-folder}\bin\setenv.bat
containing one line:set JAVA_OPTS=-Dfile.encoding=UTF-8 -Xms128m -Xmx1024m -XX:PermSize=64m -XX:MaxPermSize=256m
-
Alejandro Pablo Tkachuk about 8 yearsThe correct solution is to address the memory leak problems and resolve them. If you registered JDBC Drivers, unregister them. You can use a javax.servlet.ServletContextListener. I have posted a solution below with a sample code to unregister drivers / threads / etc.
-
Zeb over 7 years@Deckard going into the Tomcat/bin directory and running tomcat6w.exe. Under the "Java" tab, add the arguments to the "Java Options" box. Click "OK"
-
gzmask over 7 yearslet's see... 2012 ppl say 1024, 2013 is 2048, 2014 it was 4096 and 2015 arrives at 8192. Now just spend that $100 for your 16384.
-
Chris Sim about 7 yearsThank you for your best detailed answer (Note : click "Open launch configuration" to open "edit configuration" window... but I used the following parameters: "-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled"
-
LucaP almost 7 yearsWhat if I'm running a WebLogic?
-
Rostislav V almost 7 yearsNote that CMSClassUnloadingEnabled is enabled by default
-
jonasespelita almost 6 yearsAny reason why these aren't enabled by default?
-
Edward Torbett over 4 yearsI know it's been over 8 years since I wrote this, but somewhere between then and now I found a deeper root cause and solution. This was that while all of the classes within the webapp are owned by the context classloader, the thread that invokes the startup and shutdown callback is owned by the parent classloader. This means that if the shutdown code initialises a thread-local variable, this will cause the parent classloader to end up holding a reference to the context classloader, preventing good cleanup.
-
Edward Torbett over 4 yearsLuckily, there's a very simple fix - move all code currently in the shutdown method into a new Thread object's run method. Then in the shutdown method, start this thread and wait for it to complete. The cleanup code will be executed identically, but any thread-local variables will remain bound to the context classloader instead of leaking.
-
lpkej about 4 yearsWell I had same issue, so all I did is XX:MaxPermSize=131072m :)
-
srk over 2 years
MetaSpace
also can go OutOfMemory