OutOfMemoryError: PermGen Space -- Jasper Report with Spring running on Tomcat

13,077

Solution 1

Thank you everyone for giving solution about this issue, I have identified the problem specifically to my situation and here is the solution:

Use .jasper instead of .jrxml as template !

As we know .jasper is a compiled template as well as .jrxml is ASCII source code for the template, so if we use raw source code file (jrxml) as template in current spring application then at least spring frame work has to compile the source code file. That's a question of efficiency left to Spring framework as it is the jasper bean to handle the compilation and it is not guaranteed the compilation executed only once and only happens when the application starting.

In short, after replace all templates with .jasper file, the log size has been significantly reduced and haven't seen the out of memory issue any more. I guess Spring container may be consume a lot of resource to compile jrxml to jasper at runtime. So it could be something should've improved by Jasper or Spring....

Solution 2

The exception occurs when there are too many .class files in the permgen space in the JVM which cannot be garbage collected due to its references to an object outside the AppClassLoader. It generally points out to some memory leak your applciation.

This post has a lucid explanation of java.lang.OutOfMemoryError: PermGen space error and a following post has suggestions on how to fix it. A similiar (but not exactly the same) question was asked on SO, letting you know if you missed it. I hope it helps.

As jakub has mentioned setting -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled or setting a higher value for XX:MaxPermSize might work for you. But from what I have read, it isn't a permanent solution it seems. (I am not a master in this :)).

Solution 3

Try setting these parameters in your VM. These should enable GC cleaning your permGen.

-XX:+UseConcMarkSweepGC
-XX:+CMSPermGenSweepingEnabled
-XX:+CMSClassUnloadingEnabled

Solution 4

I have developed a web application which uses JasperReports 4.5.1

I use Tomcat 6.0.26 as a container. (Win7, JDK 1.6.0_25)

When shutdown the tomcat,it throw :

The web application created a ThreadLocal with key of type [net.sf.jasperreports.engine.util.JRFontUtil$1] (value [net.sf.jasperreports.engine.util.JRFontUtil$1@7892f1]) and a value of type [java.util.HashSet] (value [[]]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.

Please visit the website:

http://community.jaspersoft.com/questions/534340/memory-leak-jr-373

Share:
13,077
Dreamer
Author by

Dreamer

Updated on July 29, 2022

Comments

  • Dreamer
    Dreamer almost 2 years

    Our web application encounter a complicated situation

    It is a Spring application developed by STS/Tomcat 7. After the application been integrated with Jasper report 4.6.0, it always throw `OutOfMemoryError: PermGen Space. Then the only way to get it work is to restart the application. But after a while it happen again. Here is log before the exception:

    Oct 17, 2012 3:42:27 PM org.apache.jasper.compiler.TldLocationsCache tldScanJar
    INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
    Oct 17, 2012 3:42:30 PM org.apache.catalina.core.ApplicationDispatcher invoke
    SEVERE: Servlet.service() for servlet jsp threw exception
    

    Here is a section within the exception where I found something about Jasper:

    at org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:442)
    at org.apache.jasper.compiler.Compiler.compile(Compiler.java:378)
    at org.apache.jasper.compiler.Compiler.compile(Compiler.java:353)
    at org.apache.jasper.compiler.Compiler.compile(Compiler.java:340)
    at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:646)
    at org.apache.jasper.servlet.JspServletWrapper.loadTagFile(JspServletWrapper.java:240)
    at org.apache.jasper.compiler.TagFileProcessor.loadTagFile(TagFileProcessor.java:578)
    at org.apache.jasper.compiler.TagFileProcessor.access$000(TagFileProcessor.java:49)
    at org.apache.jasper.compiler.TagFileProcessor$TagFileLoaderVisitor.visit(TagFileProcessor.java:655)
    

    Here are a few findings when the situation occurs:

    1. The issue can happen on page without any Jasper Report components. It seems the Jasper Report bean is trying to find a tag lib all the time when a request is processed by the back end and responded to the front end. Normally from log file I can see above exception will not throw until all back end operations(JPA management) are complete

    2. When run log4J on debug mode, I see tons of information showing something like parsing/rendering the all components from Jasper template(textfields, pen, box...), there is a small cut from the huge log:

      2012-10-17 15:29:12,025 -- DEBUG -- org.apache.commons.digester.Digester.sax -- startElement(http://jasperreports.sourceforge.net/jasperreports,textElement,textElement)
      2012-10-17 15:29:12,025 -- DEBUG -- org.apache.commons.digester.Digester --   Pushing body text ''
      2012-10-17 15:29:12,025 -- DEBUG -- org.apache.commons.digester.Digester --   New match='jasperReport/summary/band/textField/textElement'
      2012-10-17 15:29:12,025 -- DEBUG -- org.apache.commons.digester.Digester --   Fire begin() for FactoryCreateRule[className=net.sf.jasperreports.engine.xml.JRTextElementFactory, attributeName=null, creationFactory=net.sf.jasperreports.engine.xml.JRTextElementFactory@12dc6007]
      2012-10-17 15:29:12,025 -- DEBUG -- org.apache.commons.digester.Digester -- [FactoryCreateRule]{jasperReport/summary/band/textField/textElement} New net.sf.jasperreports.engine.design.JRDesignTextField
      2012-10-17 15:29:12,025 -- DEBUG -- org.apache.commons.digester.Digester.sax -- ignorableWhitespace()
      

      Still, this log is generated when a request to the page which does not contains any Jasper component.

    I did some research but still cannot find the solution to this issue.

    1. The first question is even there is a jasperreport bean in the application why it is always running when it is not even autowired with current service(meaning current page doesn't have any jasper component). Is there a solution/answer to this situation?

    2. Also from the exception message At least one JAR was scanned for TLDs yet contained no TLDs. at org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:442)

      should comes from Tomcat, and Tomcat never contains any JSTL jar, then I assume it cannot find a match TLD to parse jasper report hence do a full scan of all jars. If so, then how come there is huge amount of debug logs from org.apache.commons.digester.Digester actually seems busy on parsing the jasper template?

    In general, make this thread is just try to figure out a solution to the probelm, and also find an answer to why Jasper is so active on a place doesn't require it, and how we can let tomcat properly parsed the templates?

    Apologize if too verbose, and thanks for any hints.

  • Dreamer
    Dreamer over 11 years
    Thank you. Are you sure we do this to the JVM not Tomcat? Is there performance impact by this change?
  • Frank Pavageau
    Frank Pavageau over 11 years
    The PermGen OOM usually occurs because the GC ran but could not free memory, not because the GC is not taking care of the PermGen.
  • eis
    eis over 11 years
    to actually diagnoze what is the problem, you should add also -XX:+HeapDumpOnOutOfMemoryError so you would get a heap dump. Unsure if it works on permgen error, but I would recommend to try. That heap dump should then be run through with MAT or similar.
  • jakub.petr
    jakub.petr over 11 years
    Yes, you should set these in Tomcat configuration, so when it starts VM for your apps than it starts with these parameters. We are using these with GlassFish and didn't notice any performance impact, just PermGen error stopped showing up.
  • Marouane Lakhal
    Marouane Lakhal about 7 years
    Nice posts on the links. If someone need some insight on what's going on better read those posts. Thank you.