3

Tomcat7を実行しているLinux(ubuntu)サーバーがあります。サーバーには 1GB の RAM があり、Java からヒープ スペース エラーがスローされます。

基本的に何が起こっているかというと、Tomcat サーバー (サーブレット コードを実行している) が、割り当てるメモリがなくなったため、例外をスローしています。私のコードはかなりスリムなので、それが問題だとは思いません。

htop を見ると、多くの Java ログ プロセスが表示されます。これらのプロセスが約 30 あります。

ps ax | grep java
 7412 pts/0    Sl     0:02 /usr/bin/java -Djava.util.logging.config.file=/usr/share/tomcat/apache-tomcat-7.0.29/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/share/tomcat/apache-tomcat-7.0.29/endorsed -classpath /usr/share/tomcat/apache-tomcat-7.0.29/bin/bootstrap.jar:/usr/share/tomcat/apache-tomcat-7.0.29/bin/tomcat-juli.jar -Dcatalina.base=/usr/share/tomcat/apache-tomcat-7.0.29 -Dcatalina.home=/usr/share/tomcat/apache-tomcat-7.0.29 -Djava.io.tmpdir=/usr/share/tomcat/apache-tomcat-7.0.29/temp org.apache.catalina.startup.Bootstrap start
 7426 pts/0    D+     0:00 grep --color=auto java
25937 ?        Sl    13:12 /usr/bin/java -Djava.util.logging.config.file=/usr/share/tomcat/apache-tomcat-7.0.29/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/share/tomcat/apache-tomcat-7.0.29/endorsed -classpath /usr/share/tomcat/apache-tomcat-7.0.29/bin/bootstrap.jar:/usr/share/tomcat/apache-tomcat-7.0.29/bin/tomcat-juli.jar -Dcatalina.base=/usr/share/tomcat/apache-tomcat-7.0.29 -Dcatalina.home=/usr/share/tomcat/apache-tomcat-7.0.29 -Djava.io.tmpdir=/usr/share/tomcat/apache-tomcat-7.0.29/temp org.apache.catalina.startup.Bootstrap start

これらの Java プロセスは時間の経過とともにゆっくりとメモリ リークを起こします。また、Tomcat サーバーで使用できる RAM が 1 GB しかないため、ヒープ スペースの例外がスローされ始めます。

私はlog4jをいじりました(ただし、オフにする必要があります)。見つけた構成でログをオフにするためにできる限りのことをしました。

どんな助けでも素晴らしいでしょう、私はこれらのプロセスを取り除く必要があるだけです-それらは貪欲になる方法です. ありがとう!

〜ダン

編集: 詳細情報:

これはおそらく、これを完全に解決するのに十分なヒントです - 私はいくつかの起動デバッグをチェックし、これを思いつきました:

    Oct 02, 2012 8:50:08 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads

SEVERE: The web application [/NMVServer] appears to have started a thread named [http-bio-8080-exec-53] but has failed to stop it. This is very likely to create a memory leak.
Oct 02, 2012 8:50:08 AM org.apache.catalina.loader.WebappClassLoader 
clearReferencesThreads

SEVERE: The web application [/NMVServer] appears to have started a thread named [http-bio-8080-exec-54] but has failed to stop it. This is very likely to create a memory leak.
Oct 02, 2012 8:50:08 AM org.apache.catalina.loader.WebappClassLoader 
clearReferencesThreads

SEVERE: The web application [/NMVServer] appears to have started a thread named [http-bio-8080-exec-62] but has failed to stop it. This is very likely to create a memory leak.
Oct 02, 2012 8:50:08 AM org.apache.catalina.loader.WebappClassLoader 
clearReferencesThreads

SEVERE: The web application [/NMVServer] appears to have started a thread named [http-bio-8080-exec-64] but has failed to stop it. This is very likely to create a memory leak.

私が見つけたリークの問題の 1 つは、いくつかのフォーラムによると、JDBC ドライバーhttp://bugs.mysql.com/bug.php?id=36565のバグによるものです。それは私が受け取っていた別のメッセージを解決します。

私は周りを見回しており、これは非常に便利であることがわかりました:

http://wiki.apache.org/tomcat/MemoryLeakProtection

今、私はあなたのすべてのアドバイスに感謝します。

〜ダン

4

2 に答える 2

3

私は一般的に、Java のロギング コードが十分にテストされていることを期待しています。ロギング構成によってログ出力が生成されない場合、オーバーヘッドは低くなります。htop の結果は、おそらく tomcat のアイドル スレッド ステータスを示しています。

ログに記録している可能性がありますが、アプリケーションまたは別のコンポーネントがメモリ リークを起こしている可能性があるすべての方法を検討することをお勧めします。

すべての JVM には、メモリ リークを診断するための非常に優れたツールがあります。このようなスレッドでは、何が起こっているのかを知るための優れた方法について議論しています。

編集:いくつかの考え

多数のリクエストでHttpServletRequest.getSession(). Managerコンポーネントの構成はContext内にあり、無制限のセッションのデフォルトは -1 です。

既知のメモリ リークが発生した場合に備えて、 Tomcat のバージョンを現在の問題の修正リストで確認してください。

最後に、Tomcat 7 には、リソースが解放されていないことを示す可能性のあるJreMemoryLeakPreventionListenerが含まれています。

于 2012-09-24T09:45:02.007 に答える
1

通常、Tomcat にはスレッド プールがあります。Java EE 仕様では、各 HTTP 要求を処理するために個別のスレッドを開始する必要があります。Tomcat にはスレッド プールがあり、スレッドを作成して終了する代わりに、このプールからスレッドを再利用します。詳細はこちら

たとえば、Tomcat の最大メモリ制限を変更setenv.sh(またはそれぞれ setenv.bat)することで設定できます。

CATALINA_OPTS='-Xms512m -Xmx1024m'

Oracle JVM の詳細については、こちらを参照してください。

しかし実際には、最も重要なことは、JVM 内のメモリ割り当てを追跡することです。これにはJava VisualVMが必要です。

于 2012-09-30T22:37:55.420 に答える