Wiki Spaces

Documentation
Projects
Resources

Get Help from Others

Q&A: Ask OpenMRS
Discussion: OpenMRS Talk
Real-Time: IRC Chat | Slack

Documentation

Page tree
Skip to end of metadata
Go to start of metadata

java.lang.OutOfMemoryError: PermGen space

This error will appear after Tomcat has exhausted all of its memory. This is typically caused by using the "Update" or "Reload" function on a webapp too many times. Currently, Tomcat and/or the JVM isn't releasing all of the memory when a webapp is destroyed/recreated. After several reloads Tomcat is out of its allotted memory and will hang or freeze.

Solutions

  • Developers: Restart Tomcat after several updates/reloads
  • Developers and Implementers: Allow Tomcat to use more memory. This will not stop the error, just prolong times between tomcat restarts. Follow the 'Java Heap Size' solution instructions.
  • Implementers: Tell Tomcat to not leak memory

java.lang.OutOfMemoryError: PermGen space (Maven/Jetty)

This error will appear if Jetty (JVM) has exhausted all of its memory. This can occur on first time install of OpenMRS (during a DB create/upgrade process). To solve this problem one needs to increase the memory available to JVM (i.e. to Maven -- which invokes Jetty)

To solve the problem, set the following environment variable (MAVEN_OPTS) on your machine:

Increasing memory by setting env variable
export MAVEN_OPTS="-Xmx1024m -Xms1024m -XX:PermSize=256m -XX:MaxPermSize=512m"

Java Heap Size Exception

A Java Heap Size error occurs because of certain memory intensive actions (like Data Exporting). The new Spring managed API uses a lot of memory to cache the xml beans. You may need to increase the default memory allocation.

Solutions

Three options for increasing Tomcat's allowed memory:

  • Start Tomcat with these parameters at the command line. Note: The current ANT task "Start Tomcat" will start with these options.

    -Xmx512m -Xms512m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewSize=128m

  • If running Tomcat as a Windows Service, open up the Tomcat Monitor (TOMCAT_HOME/bin/tomcat5w.exe). Configure Tomcat -> Java -> Java Options, or go to Control Panel > Services > Apache Tomcat > Properties > Start Parameters. Append:

    -Xmx512m -Xms512m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewSize=128m

    Note 1: if you copy and paste the above into tomcat monitor, make sure that it doesn't insert an extra space at the end of each line, or tomcat will fail to start.
    Note 2: If running 64 bit version of Tomcat, you have to edit the Windows Registry HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Procrun 2.0\Tomcat5\Parameters\JavaJVM settings in Registry
    Note 3: It no longer works to set these parameters through a JAVA_OPTS environment variable

  • If running Tomcat as a Linux daemon, open the /etc/init.d/Tomcat.sh script and append the parameters to the CATALINA_OPTS variable: i.e.

    If CATALINA_OPTS is already set to this: CATALINA_OPTS="-Djava.library.path=/opt/tomcat/lib/.libs"
    then change it to this: CATALINA_OPTS="-Djava.library.path=/opt/tomcat/lib/.libs -Xmx512m -Xms512m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewSize=128m"

    For Ubuntu, see Jonah Mwogi's directions in the comments below .


Solution for Tomcat memory leak:

In <TOMCAT HOME>/conf/web.xml file, in the jsp servlet definition add the following element: 

<init-param>
  <param-name>enablePooling</param-name>
  <param-value>false</param-value>
</init-param>


Finding Memory Solutions

OpenMRS developers use YourKit Profiler to discover and debug memory and cpu consumption.

YourKit is kindly supporting OpenMRS with its full-featured Java Profiler. YourKit, LLC is creator of innovative and intelligent tools for profiling Java and .NET applications. Take a look at YourKit's leading software products: YourKit Java Profiler and YourKit .NET Profiler.

Profiling Summary of the OpenMRS FHIR Module.

11 Comments

  1. In my endeavors to troubleshoot tomcat memory issues i performed the following in Ubuntu 10.04:

    sudo gedit /etc/init.d/tomcat6

    Changed (~line 81):

    if [ -z "$JAVA_OPTS" ]; then
            JAVA_OPTS="-Djava.awt.headless=true -Xmx128M"
    fi

    To:

    if [ -z "$JAVA_OPTS" ]; then
            JAVA_OPTS="-Djava.awt.headless=true -Xmx1024M -Xms1024M -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewSize=128m"
    fi

    You can as well explicitly state in catalina.sh file as follows (in bold):

    #!/bin/sh

    CATALINA_OPTS="-Xms1024m -Xmx1024m"

    1. It would be better to use CATALINA_OPTS variable because it only passes the values when Tomcat is starting. On the other hand, JAVA_OPTS will affect all the other Java programs. So if you have assigned very high memory, say, -Xms=1024M to JAVA_OPTS, your OS may run out of memory.

  2. On my mac I was able to add the following line to /usr/local/Tomcat/bin/catalina.sh to solve the problem:

    JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms512m -Xmx1024m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+DisableExplicitGC"
    

    I'm not sure but I think that this strategy should work in other operating systems as well.

  3. I recommend that instead of editing /etc/init.d/tomcat6 directly, the Debian way, and thus, the Ubuntu way is to edit the file:

    /etc/default/tomcat6

    Rationale:

    /etc/init.d/tomcat6 is occasionally updated by the package maintainers and is likely to be overwritten sometime during a package upgrade. /etc/default/tomcat6 on the other hand is identified as a local configuration file and is read in by the startup scripts to load local settings. This file (/etc/default/tomcat6) is also guaranteed not to be overwritten on package upgrades.

    Editing either JAVA_OPTS or CATALINA_OPTS with the appropriate memory settings as stated in previous comments and the main article should work. 

  4. In my case ,when running the webapp using jetty I got *java.lang.OutOfmemory error PremGen space  *error : in order to fix that i have increased the eclipse JRE premgen size.

    Windows > Preferences > Installed JREs > jre... >Edit

    then added these default VM arguments 

    -Xmx1024m -XX:MaxPermSize=1024m

  5. user-924cc

    If you use Tomcat as a Service in Windows and fail with the other methods you can also change the settings like this:

    http://www.zulutown.com/blog/2009/03/12/solving-tomcat-outofmemoryerror-heap-space-and-permgen-space/

  6. I have been unable to configure Tomcat with the recommended settings running under Windows 8.1.

    The Registry path for Tomcat 7 in Windows 8.1 is

    KEY_LOCAL_MACHINE\SOFTWARE\Wow6432Mode\Apache Software Foundation\Procrun 2.0\Tomcat7\Parameters\Java\Options.

    The path is similar in Tomcat6. In fact, all that I mention appears to apply to both versions.

    When I add the string -Xmx512m -Xms512m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewSize=128m to the Options entry, the Tomcat7 service fails to load.

    My machine has 8 GB of RAM, by the way. I don't know whether this matters.

     

  7. am using openMRS 1.9.9

    but am getting this error and i don't know where to fix it , i run it through windows 7

     

    type Exception report

    message PermGen space

    description The server encountered an internal error that prevented it from fulfilling this request.

    exception

    java.lang.OutOfMemoryError: PermGen space
    	java.lang.ClassLoader.defineClass1(Native Method)
    	java.lang.ClassLoader.defineClass(ClassLoader.java:791)
    	java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    	java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    	java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    	java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    	java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    	java.security.AccessController.doPrivileged(Native Method)
    	java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    	org.apache.jasper.servlet.JasperLoader.loadClass(JasperLoader.java:132)
    	org.apache.jasper.servlet.JasperLoader.loadClass(JasperLoader.java:63)
    	org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:172)
    	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:369)
    	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
    	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    	javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    	org.openmrs.web.filter.JspClassLoaderFilter.doFilter(JspClassLoaderFilter.java:47)
    	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:70)
    	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:70)
    

    note The full stack trace of the root cause is available in the Apache Tomcat/7.0.42 logs

  8. The OutOfMemoryError example ("Increasing memory by setting env variable") specifies differents values for PermSize and MaxPermSize, which is not recommended.

    Every resize of the permanent generation will cause a full GC (Garbage Collect).

    Better specify both to the same value. (For low memory and low load  you may make another choice, though.)

    Use "jmap -heap" to get the actual size of the permanent generation.

  9. On Ubuntu 14.04, if you have installed tomcat from Ubuntu repository (apt-get install), its recommended to change configurations for tomcat config file at:

    /etc/default/tomcat7

    And then changing the JAVA_OPTS variable to the above, i.e:

    JAVA_OPTS="-Djava.awt.headless=true -Xmx1024M -Xms1024M -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewSize=128m"