Webアプリケーションのパフォーマンスが低下したり障害が発生した場合は、アプリケーションのパフォーマンス分析サービスを使用して、アプリケーションの内部動作をすばやく表示できるようにする多くの問題を解決できます。WhaTap Labsはアプリケーションのパフォーマンス分析サービスを開発する会社ですが、お客様に代わって直接アプリケーションの問題を分析して解決することもあります。
アプリケーションの問題の間に多くの顧客が苦労するケースはJVM Crashです。JVM Crashは、JVM自体が外部要因で終了する場合であるため、アプリケーションパフォーマンス分析サービスとして見られる情報は限られていますが、代わりにGoogle検索やIBMサイトなどのさまざまなパスで解決できます。それでは、JVM Crashの問題を解決する方法をお教えします。
Java仮想マシン(JVM)は、Javaプログラムが実行される仮想マシンです。1つのVMなので、内部でシグナルを与えないと終了しないように設計されています。逆に、PCでたまに出会うブルースクリーンのような理由がわからなく止まることもあります。この場合を JVM では Crash といいます。
JVM Crashは発生頻度が低く、原因も作成したアプリケーションに起因しないため、開発者は原因を特定するのが困難です。しかし、PCで出会うブルースクリーン画面にもエラーコード、メモリアドレスが出てくるように、JVMも死ぬ前に糸口を震わせていきます。
アプリケーションはすべてのバグで平等です。一定の規模を超えるすべてのアプリケーションは、重要またはマイナーなBugを持っています。
JVMも当然Bugがあります。そしてそのバグがCrashを作ったりもします。アプリケーションの問題としてJVMにCrushが発生するのもJVMの問題です。この場合でも正常なJVMであれば、アプリケーションのエラーを親切にException, Errorとして知らせてCrashされることはないはずです。JVMが未知の理由でCrushした場合、それはJVM Bugです。
幸いなことに、JDKのバグフィックスリストを簡単に見つけることができます。IBMの場合、タイプ別にCrash、Hang、Performanceなどに分類しておきます。以下は8.0フィックスパックのリストです。Defect Typeを見ると、Crash、Issue、Hangなどに分類されたものが見られます。
上記のバグ修正リストでIJ11480:CRASH IN FFISYS CALL IN ZOSを選択すると、以下のようにそのバグの詳細が表示されます。
もちろん、Oracleでもバグフィックスリストを管理しています。
JVM が異常終了すると hs_err_pid(hotspot), javacore(IBM)を残すようになっています。ただし、ログが生成されていないか見つからない場合は、関連する環境変数、オプションなどを適用してログが残るようにする必要があります。
ログファイルが作成される場所がわからない場合は、次のようにログファイルを作成する場所を指定してください。
Oracleの場合はproduct flagを使用します。
XX:ErrorFile=/var/log/java/hs_err_pid%p.log
Java Platform, Standard Edition Troubleshooting Guide > Location of Fatal Error Log
IBM の場合は、.profile 環境変数を使用します。
export IBM_JAVACOREDIR=/somewhere/dumpdir
Changing the location of javacore, heapdump and core file generated by TIP
それでもログが残っていない場合は、次の状況を疑うことができます。
以下は、Oracle hotspot hs_err_pidの内容です。 上部には発生理由と発生位置があります。
ここでSIGSEGVはSegmentation faultを意味し、Crashの発生理由です。
その他代表的な発生事由で
Problematic frameは発生位置を示します。
上記の例は、libjvm.soの0x7c091bの場所で発生したと記録されているため、ユーザーが実装した領域のエラーではないことがわかります。
同じファイルをもっと詳しく見てみましょう。
Dumpの内容を確認すると、0x7c091bはJava Compilerが呼び出したNodeであることがわかります。Java bytecodeを機械語に翻訳する過程で発生したJVMエラーでCrashが発生したと判断できます。
IBM Javaの場合はjavacoreを残します。Oracle hotspotと同様に、上部に発生理由と発生場所があります。
発生の理由である Dump Event "gpf" は general protection fault であり、Segmentation fault と同じです。
やはり下にModule: /usr/java8_64/jre/lib/ppc64/compressedrefs/libj9thr29.soという発生位置が記録されています。
クラッシュの原因が SIGSEGV(Segmentation fault)または gpf(general protection fault)で、発生位置がJDK 内部モジュールである場合は、JDK Fixで問題を解決できます。
Oracle Hotspotのログでlibjvm.soの0x7c091bでエラーが発生したことを確認したら、Googleでその行を検索します。
検索すると、その行のバグを確認してみることができます。ステータス値が CLOSED です。対応するバグ修正を探すだけです。https://bugs.openjdk.java.net/browse/JDK-8183197
下部のCommentsを確認してください。バグ修正へのリンクを見つけることができます。
以下のリンクで、より詳細な情報を見つけることができます。 https://bugzilla.redhat.com/show_bug.cgi?id=1306558
これで、そのJDKバージョン以降のフィックスリストを確認して更新計画を立てることができます。ただし、アップデートを計画するのではなく、問題の回避方法を使用して、バグの原因に基づいてアプリケーションの構造を変更することもできます。このような場合は、アプリケーションパフォーマンス分析ツールが役に立ちます。
JDKも誰かが作成したアプリケーションです。 JDKもエラーの可能性を暗示していることを常に認識し、定期的なアップデートでより信頼性の高い環境を作成する必要があります。また、アプリケーションのパフォーマンスを上げる必要がある場合、またはアプリケーションで発生した問題が解決しない場合は、WhaTap Labs(support@whatap.io)までメールください。できるだけお手伝いさせていただきます。