10

(現在最新の) tomcat 6.0.24で Web アプリケーションを実行しているときに (現在最新の) jdk 1.6.0.18 が予期せずクラッシュしました。 600万ページビュー/日)。これは RHEL 5.2 (Tikanga) 上にあります。

クラッシュ レポートはhttp://pastebin.com/f639a6cf1にあり、クラッシュの一貫した部分は次のとおりです。

  • SIGSEGV がスローされています
  • libjvm.so で
  • eden スペースは常に満杯 (100%)

JVM は次のオプションで実行されます。

CATALINA_OPTS="-server -Xms512m -Xmx1024m -Djava.awt.headless=true"

また、 http://memtest.org/を使用して 48 時間 (メモリ全体の 14 パス)、エラーなしでハードウェアの問題についてメモリをテストしました。

GC の傾向やスペースの枯渇を検査できるようにしまし-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStampsたが、疑わしいものは何もありません。GC とフル GC は予測可能な間隔で発生し、ほぼ常に同じ量のメモリ容量を解放します。

私のアプリケーションは、ネイティブ コードを直接使用していません。

次にどこを見るべきかについてのアイデアはありますか?

編集 - 詳細情報:

1) この JDK にはクライアント vm がありません。

[foo@localhost ~]$ java -version -server
java version "1.6.0_18"
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) 64-Bit Server VM (build 16.0-b13, mixed mode)

[foo@localhost ~]$ java -version -client
java version "1.6.0_18"
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) 64-Bit Server VM (build 16.0-b13, mixed mode)

2) O/S の変更はできません。

3) 問題を隠す可能性があるため、JMeter ストレス テスト変数を変更したくありません。JVM をクラッシュさせるユース ケース (現在のストレス テスト シナリオ) があるので、クラッシュを修正し、テストを変更したくありません。

4)アプリケーションの静的分析を行いましたが、深刻な問題は何も起こりませんでした。

5) メモリは時間が経っても増加しません。メモリ使用量は、非常に安定した傾向で (起動後) 非常に迅速に平衡化し、疑わしいとは思われません。

6) /var/log/messages には、クラッシュの前または最中に有用な情報が含まれていません。

詳細情報: mod_jk 1.2.28 を使用して tomcat の前に apache (2.2.14) があったことを忘れていました。JVMクラッシュがJVM(tomcatコネクタ)に接続するmod_jkネイティブコードに関連している場合に備えて、現在、Apacheなしでテストを実行しています。

その後 (JVM が再びクラッシュした場合)、アプリケーションからいくつかのコンポーネント (キャッシング、ルセン、クォーツ) を削除してみて、後で jetty を使用してみます。クラッシュは現在 4 時間から 8 日間の間いつでも発生しているため、何が起こっているのかを突き止めるにはかなりの時間がかかる可能性があります。

4

7 に答える 7

4

コンパイラ出力はありますか? つまりPrintCompilation(特に勇気があるなら、LogCompilation)。

コンパイラが何をしているかを見て、最終的に(これは電球の瞬間まで長い時間がかかりました)、オラクルのjdbcドライバーの特定のメソッドのコンパイルによってクラッシュが発生したことに気づきました。 .

基本的に私がすることは次のとおりです。

  • PrintCompilation をオンにします
  • それはタイムスタンプを与えないので、そのログファイルを監視し(毎秒スリープして新しい行を出力するなど)、メソッドがコンパイルされた(またはコンパイルされなかった)ときに報告するスクリプトを記述します
  • テストを繰り返す
  • コンパイラの出力をチェックして、クラッシュが何らかのメソッドのコンパイルに対応しているかどうかを確認します
  • パターンがあるかどうかを確認するために、さらに数回繰り返します

識別可能なパターンがある場合は、.hotspot_compiler (または .hotspotrc) を使用して、問題のあるメソッドのコンパイルを停止し、テストを繰り返して、失敗しないかどうかを確認します。明らかに、あなたの場合、このプロセスには理論的には数か月かかる可能性があります。

いくつかの参考文献

もう 1 つは、使用している gc アルゴリズムを体系的に変更し、 gc アクティビティに対するクラッシュ時間チェックすることです (たとえば、古い gc と相関関係があるか、TLAB はどうですか?)。ダンプは、並列スカベンジを使用していることを示しているので、試してください

  • シリアル(若い)コレクター(IIRCはパラレルオールドと組み合わせることができます)
  • ParNew + CMS
  • G1

異なる GC アルゴで再発しない場合は、それが原因であることがわかります (そして、GC アルゴを変更するか、古い JVM をさかのぼる以外に解決策はありません。そのアルゴのバージョンが壊れていないことがわかるまで) )。

于 2010-02-28T21:01:45.020 に答える
3

いくつかのアイデア:

  • 別の JDK、Tomcat、および/または OS バージョンを使用する
  • テスト パラメータを少し変更します。たとえば、1 日あたり 720 万ページビューで 25 スレッドです。
  • メモリ使用量の監視またはプロファイリング
  • ガベージ コレクターをデバッグまたは調整する
  • 静的および動的解析を実行する
于 2010-02-24T03:19:32.703 に答える
2

別のハードウェアを試しましたか? 64 ビット アーキテクチャを使用しているようです。私自身の経験では、32 ビットの方が高速で安定しています。おそらくハードウェアの問題もどこかにあるでしょう。「4 ~ 24 時間」のタイミングは、単なるソフトウェアの問題であるためにかなり広がっています。システムログにエラーはないとおっしゃっていますが、私はかなり外れている可能性があります。それでも試してみる価値があると思います。

于 2010-02-24T22:50:41.027 に答える
1

私があなただったら、私は次のことをします:

  • 少し古いTomcat/JVMバージョンを試してください。あなたは最新かつ最高のものを実行しているようです。2つのバージョンかそこらを下げて、おそらくJRockitJVMを試してみます。
  • アプリの実行中にスレッドダンプ(kill -3 java_pid)を実行して、完全なスタックを確認します。現在のダンプは、多くのスレッドがブロックされていることを示していますが、どこでブロックされているのかは明確ではありません(I / O?内部ロックの枯渇?他に何か?)。ランダムなスレッドダンプをクラッシュ直前のスレッドダンプと比較するために、kill-3を毎分実行するようにスケジュールすることもできます。
  • Linux JDKが停止するのに対し、Windows JDKは例外を適切にキャッチできる(当時はStackOverflowExceptionでした)場合があります。コードを変更できる場合は、トップクラスのどこかに「catchThrowable」を追加してください。念のため。
  • GCチューニングオプションで遊んでください。同時GCのオン/オフを切り替え、NewSize/MaxNewSizeを調整します。そして、はい、これは科学的ではありません-むしろ実用的な解決策の切実な必要性。詳細はこちら: http: //java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html

これがどのように整理されたか教えてください!

于 2010-02-24T22:43:24.343 に答える
1

サーブレット コンテナを Tomcat から Jetty http://jetty.codehaus.org/jetty/に切り替えてみてください。

于 2010-02-24T21:01:57.263 に答える
1

あなたの記憶は時間の経過とともに成長しますか?その場合は、メモリ制限を低く変更して、メモリが使い果たされたときにシステムがより頻繁に失敗するかどうかを確認することをお勧めします。

次の場合、問題をより早く再現できますか?

  • JVM で使用できるメモリを減らしますか?
  • 利用可能なシステム リソースを減らします (つまり、システム メモリを使い果たし、JVM に十分なリソースがありません)。
  • ユースケースをより単純なモデルに変更しますか?

私が使用した主な戦略の 1 つは、問題の原因となっているユース ケースを特定することです。これは一般的な問題である場合もあれば、ユース ケース固有の問題である場合もあります。ユース ケースの開始と停止をログに記録して、どのユース ケースが問題を引き起こす可能性が高いかを判断できるかどうかを確認してください。ユースケースを半分に分割する場合、どちらの半分が最も速く失敗するかを確認します。これは、失敗のより頻繁な原因である可能性があります。当然のことながら、各構成を数回試行すると、測定の精度が向上します。

また、サーバーを変更してほとんど作業を行わないようにするか、サーバーが行っている作業をループすることも知られています。1 つはアプリケーション コードの作業をより困難にし、もう 1 つは Web サーバーとアプリケーション サーバーの作業をより困難にします。

がんばれ、ジェイコブ

于 2010-02-24T03:26:47.247 に答える
1

代わりに 32 ビット JVM に移行するオプションはありますか? これは、Sun が提供する最も成熟した製品だと思います。

于 2010-02-27T09:10:21.820 に答える