一尘不染

OutOfMemoryError:PermGen空间—在Tomcat上运行Spring的Jasper报告

tomcat

我们的Web应用程序遇到了复杂的情况

它是STS /开发的Spring应用程序Tomcat 7。将应用程序与集成后Jasper report 4.6.0,它总是抛出`OutOfMemoryError:PermGen
Space。然后,使其正常工作的唯一方法是重新启动应用程序。但是过了一会儿又发生了。这是例外之前的日志:

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

这是例外中的一部分,我在其中找到了一些有关Jasper

    at org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:442)
    at org.apache.jasper.compiler.Compiler.compile(Compiler.java:378)
    at org.apache.jaspercompiler.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)

发生这种情况时,有一些发现:

  1. 没有任何Jasper Report组件的页面上可能会发生此问题。似乎Jasper Report bean一直在尝试查找标记lib a request is processed by the back end and responded to the front end。通常,从日志文件中可以看到,在所有后端操作(JPA管理)完成之前,不会引发上述异常

  2. 在调试模式下运行log4J时,我看到大量信息,例如从Jasper模板(文本字段,钢笔,盒子…)解析/渲染所有组件,从巨大的日志中可以看到一个小片段:

        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()

尽管如此,当对该页面的请求不包含任何Jasper组件时,仍会生成此日志。

我做了一些研究,但仍然找不到解决此问题的方法。

  1. 第一个问题是jasperreport bean应用程序中甚至存在一个问题,即使它没有与当前服务自动连线(为什么当前页面没有任何碧玉组件),为什么它总是运行。有这种情况的解决方案/答案吗?

  2. 同样从异常消息中,至少扫描了一个JAR来查找TLD,但其中不包含TLD。在org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:442)

应该来自Tomcat,然后Tomcat never contains any JSTL jar,我假设它找不到匹配的TLD来解析jasper报告,因此对所有jar进行完整扫描。如果是这样,那么为什么org.apache.commons.digester.Digester在解析jasper模板时似乎却忙于大量调试日志呢?

通常,使该线程只是试图找出解决方案的方法,并找到一个答案,为什么Jasper如此活跃在不需要它的地方,以及如何让tomcat正确解析模板?

如果太冗长,表示歉意,并感谢您提供任何提示。


阅读 327

收藏
2020-06-16

共1个答案

一尘不染

谢谢大家提供有关此问题的解决方案,我已经根据我的具体情况确定了问题,以下是解决方案:

使用.jasper而不是.jrxml作为模板!

我们知道这.jasper是一个已编译的模板以及.jrxml该模板的ASCII源代码,因此,如果在当前spring应用程序中使用原始源代码文件(jrxml)作为模板,则至少spring框架工作必须编译该源代码文件。这是Spring框架的效率问题,因为它是处理编译的jasper
bean,并且不能保证编译仅执行一次并且仅在应用程序启动时发生。

简而言之,将所有模板替换为.jasper文件后,日志大小已显着减小,并且不再出现内存不足的问题。我猜想Spring容器可能会在运行时消耗大量资源来将jrxml编译为jasper。因此,Jasper或Spring应该可以对它进行一些改进。

2020-06-16