Dealing with "java.lang.OutOfMemoryError: PermGen space" error

Viewed 1056240

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?

34 Answers

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.

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.

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.

Use the command line parameter -XX:MaxPermSize=128m for a Sun JVM (obviously substituting 128 for whatever size you need).

Try -XX:MaxPermSize=256m and if it persists, try -XX:MaxPermSize=512m

resolved this for me as well; however, I noticed that the servlet restart times were much worse, so while it was better in production, it was kind of a drag in development.

I have a combination of Hibernate+Eclipse RCP, tried using -XX:MaxPermSize=512m and -XX:PermSize=512m and it seems to be working for me.

The configuration of the memory depends on the nature of your app.

What are you doing?

What's the amount of transactions precessed?

How much data are you loading?

etc.

etc.

etc

Probably you could profile your app and start cleaning up some modules from your app.

Apparently this can occur after redeploying an application a few times

Tomcat has hot deploy but it consumes memory. Try restarting your container once in a while. Also you will need to know the amount of memory needed to run in production mode, this seems a good time for that research.

If any one is struggling with the same error in netbeans, then here is how I fixed it.

In Netbeans:

Go to services tab --> Right on server -->Choose properties --> go to platform tab -->Inside vm options type -Xms1024m

In my case, I have given -Xms4096m

Here is the screenshot:

enter image description here

To who is getting this same problem in IntelliJ when trying to debug JBoss Application: I just added this -XX: MaxPermSize = 128m to the VM Options In Run/Debug COnfigurations. You can increase it to 256m to be more guaranteed that will work.

Increase Tomcat Memory

C:\Program Files\Apache Software Foundation\Tomcat 9.0\bin

or anywhere you used tomcat. and run tomcat9w or any version you used.

after that follow the picture

enter image description here

Change 128 to 1024 and also max change it to 1024 or more as you want.

Related