8

私たちの 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.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)

この状況が発生した場合の調査結果を次に示します。

  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、現在のサービスで自動配線されていない場合でもアプリケーションが常に実行されている理由 (現在のページに jasper コンポーネントがないことを意味します) がアプリケーション内にあることです。この状況に対する解決策/答えはありますか?

  2. また、例外メッセージから、少なくとも 1 つの JAR が TLD に対してスキャンされましたが、TLD は含まれていませんでした。org.apache.jasper.compiler.JDTCompiler.generateClass (JDTCompiler.java:442) で

    はTomcatから来るべきでありTomcat never contains any JSTL jar、ジャスパーレポートを解析するための一致するTLDを見つけることができないため、すべてのjarファイルのフルスキャンを実行します。org.apache.commons.digester.Digesterもしそうなら、ジャスパー テンプレートの解析で実際に忙しいように見える大量のデバッグ ログがあるのはなぜですか?

一般に、このスレッドを作成して、問題の解決策を見つけようとするだけでなく、ジャスパーがそれを必要としない場所で非常にアクティブである理由と、Tomcat にテンプレートを適切に解析させる方法についての答えを見つけます。

冗長すぎる場合はお詫び申し上げます。また、ヒントをありがとうございます。

4

5 に答える 5

9

この問題について解決策を提供してくれてありがとう、私は自分の状況に特に問題を特定しました。解決策は次のとおりです。

テンプレートとして .jrxml の代わりに .jasper を使用してください。

私たちが知って.jasperいるように、コンパイルされたテンプレートとテンプレート.jrxmlのASCIIソースコードであるため、現在のSpringアプリケーションで生のソースコードファイル(jrxml)をテンプレートとして使用する場合、少なくともSpringフレームワークはソースコードファイルをコンパイルする必要があります. コンパイルを処理するのは jasper Bean であり、アプリケーションの起動時にのみコンパイルが実行されるとは限りません。

つまり、すべてのテンプレートを .jasper ファイルに置き換えた後、ログ サイズが大幅に縮小され、メモリ不足の問題が発生しなくなりました。Spring コンテナーは、実行時に jrxml を jasper にコンパイルするために多くのリソースを消費する可能性があると思います。したがって、JasperまたはSpringによって改善されるべきものである可能性があります....

于 2013-03-19T16:35:55.970 に答える
7

この例外は、JVM の permgen スペースに、AppClassLoader 外のオブジェクトへの参照が原因でガベージ コレクションできない .class ファイルが多すぎる場合に発生します。一般に、アプリケーションのメモリ リークを指摘します。

この投稿には java.lang.OutOfMemoryError: PermGen space error の明快な説明があり、次の投稿には修正方法に関する提案があります。SO で同様の (ただしまったく同じではない)質問があり、見逃した場合はお知らせします。お役に立てば幸いです。

jakubが言及したよう-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabledに、より高い値を設定または設定するXX:MaxPermSizeとうまくいくかもしれません。しかし、私が読んだことから、それは恒久的な解決策ではないようです。(私はこれのマスターではありません:))。

于 2012-10-18T02:38:53.477 に答える
2

JasperReports4.5.1を使用するWebアプリケーションを開発しました

コンテナとしてTomcat6.0.26を使用しています。(Win7、JDK 1.6.0_25)

Tomcatをシャットダウンすると、次のようにスローされます。

Webアプリケーションは、タイプ[net.sf.jasperreports.engine.util.JRFontUtil $ 1](値[net.sf.jasperreports.engine.util.JRFontUtil $ 1@7892f1])のキーとタイプ[java .util.HashSet](値[[]])が、Webアプリケーションの停止時に削除できませんでした。これにより、メモリリークが発生する可能性が非常に高くなります。

ウェブサイトをご覧ください:

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

于 2012-11-01T10:00:33.823 に答える
2

VM でこれらのパラメーターを設定してみてください。これらは permGen の GC クリーニングを可能にするはずです。

-XX:+UseConcMarkSweepGC
-XX:+CMSPermGenSweepingEnabled
-XX:+CMSClassUnloadingEnabled
于 2012-10-17T21:06:33.450 に答える
0

PermGenには主にクラスのメタデータと、定数およびインターン文字列が含まれているため、次の2つの方向で検索できます。

  • Webアプリに(多すぎる)役に立たないjarが含まれていないことを確認してください。これは、スキャンによって読み込まれる可能性があります。

  • ヒープダンプを使用して定数文字列がたくさんあるかどうか(たとえば、大きなJSPがたくさんあるかどうか)、またはコードでString.intern()を使用しているかどうかを確認します。


実際には、使用しているJavaのバージョンを指定していません。Java7では、文字列は問題にならない可能性があります。

あなたができることは、VisualGCプラグインを使用してJVisualVMでアプリケーションを観察し、世代の状態、ロードされたクラスの数、およびOOMの時点で急増しているかどうか、またはビルドが遅いかどうかを確認することです。 -上。

于 2012-10-17T21:25:01.817 に答える