ヘッダーをスキップ
Oracle® JRockit診断およびトラブルシューティング・ガイド
リリースR28
B61438-02
  目次へ移動
目次

前
 
次
 

6 JVMのクラッシュ

Javaアプリケーションは、様々な理由で動作を停止する場合があります。最も一般的な理由は、アプリケーションの動作が完了したこと、または正常に中断したことです。その他の理由としては、Javaアプリケーション・エラー、処理できない例外、またはOutOfMemoryErrorなどの回復できないJavaエラーが考えられます。場合によっては、JVM自体で正常に回復できなかった問題が起きたことを意味する、JRockit JVMクラッシュが発生する可能性があります。

この章では、JVMのクラッシュを診断し、解決する方法を説明します。この章の内容は次のとおりです。

6.1 クラッシュの分類

JVMクラッシュの診断と解決の第一段階は、クラッシュの分類です。つまり、クラッシュが発生した場所および原因を特定します。

6.1.1 クラッシュ・ファイルの使用

JRockit JVMはクラッシュすると、クラッシュした時点でのコンピュータとJVMプロセスの状態のスナップショットを作成し、状態情報を次のクラッシュ・ファイルに書き込みます。

  • .dumpファイル: .dumpファイルは、クラッシュした時点でJVMが動作していた完全なメモリー・イメージおよび環境の実行サマリーのようなテキスト・ファイルです。このファイルは、クラッシュ時にJVM自身によって作成されるファイルで、クラッシュの分類に役立ちます。場合によっては、このファイルを修復済みの問題の特定にも使用できます。このファイルから、問題の原因を判断するための十分な情報が得られることはほとんどありません。

  • .coreファイル: .coreファイルはLinuxやSolarisのようなUNIX系のシステムで生成されるバイナリ・クラッシュ・ファイルです。デフォルトで、.coreファイルは、クラッシュした時点での全JVMプロセスに関する完全な情報をキャプチャします。

  • .mdmpファイル(ミニダンプ・ファイル): .mdmpファイルは、前述した.coreファイルに相当するWindows版のファイルです。

オラクルとサポート契約を結んでいる場合は、JRockit JVMの問題のトラブルシューティングについてOracleサポートへのご連絡が可能です。バイナリ・クラッシュ・ファイル(.coreまたは.mdmp)はOracleサポートへのご連絡時に必須の情報です。

クラッシュ・ファイルの詳細は、第8章「クラッシュ・ファイルの概要」を参照してください。

6.1.2 クラッシュの種類の特定

表6-1に、発見可能な症状と、その症状に対して予想されるクラッシュの種類の一覧を示します。

表6-1 クラッシュの症状とクラッシュの種類

症状 トラブルシューティング情報は、次を参照してください

.dumpファイルは、JVMプロセスで仮想メモリーが不足していることを示しています。

6.2項「仮想メモリー不足のクラッシュ」


.coreファイル(または.mdmpファイル)のサイズが、そのオペレーティング・システムにおけるプロセスの仮想メモリー・サイズの最大値に近い値になっています。

6.2項「仮想メモリー不足のクラッシュ」


.dumpファイルは、スタック・オーバーフロー・エラーが発生したことを示しています。

6.3項「スタック・オーバーフローのクラッシュ」


Linuxのみの場合:

.dumpファイルは、LD_ASSUME_KERNEL環境変数が設定されていることを示しています。

6.4項「サポートされないLinux構成が原因のクラッシュ」


Linuxのみの場合:

非標準またはサポートされないLinux構成を使用しています。

6.4項「サポートされないLinux構成が原因のクラッシュ」


この表の一覧のいずれにも当てはまらない症状が検出されました。

6.5項「JVMクラッシュ」



6.2 仮想メモリー不足のクラッシュ

JVMは、Javaヒープ、Javaメソッド、スレッド・スタックおよびJVM内部データ構造など、様々な目的で仮想メモリーを確保します。さらに、ネイティブ(JNI)コードでも、メモリーを割り当てることができます。プロセス・サイズは、JVMによって確保されたすべてのメモリーとプロセス内で実行中のあらゆるサードパーティ・ライブラリから構成され、オペレーティング・システムの制限に従います。

JVMプロセスの仮想メモリー割当てがオペレーティング・システムの制限を超えると、JVMで仮想メモリーが不足し、クラッシュが発生する可能性があります。

この項の内容は次のとおりです。

6.2.1 仮想メモリー不足エラーの確認

仮想メモリー不足エラーのトラブルシューティングを開始する前に、まず、エラーが本当にJVMプロセスでの仮想メモリー不足によるものであるのかを確認する必要があります。

表6-2に、32ビットの各種オペレーティング・システム上のシングル・プロセスで使用可能な仮想メモリーの最大値を示します。64ビットのプラットフォームでは、仮想メモリーは実質的に無制限です。

表6-2 IA32アーキテクチャで使用可能な仮想メモリーの概算の最大値

オペレーティング・システム 仮想メモリーの概算の最大値

Windows

2GB

Windows /3GB起動オプション

3GB

Linux(標準)

3GB


仮想メモリー不足エラーの発生の有無は次の方法で確認できます。

  • テキスト・クラッシュ・ファイルを調べます。

    テキスト・クラッシュ・ファイル(.dump)は、メモリーの割当てに失敗したことを示す可能性があります。これは、JRockit JVMプロセスで仮想メモリーが不足していることを顕著に示しています。テキスト・クラッシュ・ファイルの詳細は、第8章「クラッシュ・ファイルの概要」を参照してください。

  • バイナリ・クラッシュ・ファイルのサイズをチェックします。

    JRockit JVMがクラッシュすると、バイナリ・クラッシュ・ファイル(.coreまたは.mdmp)が生成されます。デフォルトでは、バイナリ・クラッシュ・ファイルにはJVMプロセス全体のコピーが含まれます。

    バイナリ・クラッシュ・ファイルのサイズをチェックして、JVMプロセスで本当に仮想メモリーが不足しているかどうかを判断してください。

    • バイナリ・クラッシュ・ファイルのサイズが、コマンドライン・オプションの-XXdumpSizeまたはオペレーティング・システム・コマンドのulimit(LinuxおよびSolarisのみ)を使用して制限されていないことを確認します。コマンドulimit -aを使用して、LinuxおよびSolarisでクラッシュ・ファイルのサイズが無制限であることを確認してください。バイナリ・クラッシュ・ファイルのサイズが制限されていると、このコマンドを使用してJVMプロセスで仮想メモリーが不足しているかどうかを確認できません。

    • バイナリ・クラッシュ・ファイルのサイズが、ヒープのサイズより大きいかどうか確認します。これは、バイナリ・クラッシュ・ファイルが(ディスク領域の制限などによって)切り捨てられていないことを確認するためのサニティ・チェックです。

    • バイナリ・クラッシュ・ファイルのサイズが、オペレーティング・システムによって許可されているプロセスの最大サイズに近づいているかどうかをチェックします(表6-2を参照)。

6.2.2 仮想メモリー不足エラーのトラブルシューティング

JVMプロセスで仮想メモリーが不足していることを確認したら、この項の説明に従って問題のトラブルシューティングを開始できます。

6.2.2.1 JRockit JVMの最新のリリースへのアップグレード

最新のJRockit JVMリリースを実行していることを確認してください。JVMクラッシュの原因となるメモリー使用量の問題が、最新のJRockit JVMリリースで修正されている可能性があります。

6.2.2.2 Javaヒープ・サイズの削減

Javaヒープは、JVMで使用されるメモリーの合計の一部に過ぎません。Javaヒープが大き過ぎると、Javaメソッドがコンパイルおよび最適化される際、またはネイティブ・ライブラリが読み込まれる際に、JVMが起動できないか、または仮想メモリーが不足する場合があります。このような状況が発生する場合、最大ヒープ・サイズを下げてみる必要があります。

6.2.2.3 Windows/3GB起動オプションの使用

Windows 2000 Advances ServerおよびDatacenter、Windows 2003、Windows XPおよび以降のWindowsバージョンでは、/3GBオプションで(BOOT.INIファイルでオプションを指定して)オペレーティング・システムを起動するオプションがあります。このオプションを指定すると、最大仮想メモリー・プロセス・サイズは2GBから3GBに変更されます。

6.2.2.4 JNIコードのメモリー・リークのチェック

使用しているJNIコードにメモリー・リークがないかをチェックします。JNIコードが適切に記述または使用されていないと、メモリー・リークが発生する場合があります。これにより、プラットフォームでの仮想メモリーの最大サイズに達するまで、Javaプロセスが増大します。

6.2.2.5 仮想メモリーの使用状況の記録

仮想メモリーの使用状況を記録すると、仮想メモリー不足の問題の識別に役立ちます。

この項では、WindowsおよびLinuxで仮想メモリーの使用状況の統計を集める方法を説明します。

Windowsでの仮想メモリーの使用状況の記録

Windowsツールのperfmonを使用して、PrivateBytesプロセス・カウンタを記録します。JVMプロセスで予約された仮想メモリーの量に関する情報を収集してください。次の手順に従います。

  1. 「管理ツール」の「パフォーマンス・モニター」を開きます。

  2. 「+」をクリックして「カウンタの追加」ダイアログ・ボックスを開きます。

  3. 「パフォーマンス・オブジェクト」リストで「Process」を選択します。

  4. 「Process」のリストから「Private Bytes」のカウンタを選択します。

  5. 監視するプロセスを選択して「追加」をクリックします。

Linuxでの仮想メモリーの使用状況の記録

仮想メモリーの使用状況を、一定の間隔で記録するためのスクリプトを作成します。

例: top -b -n 10 > virtualmemory.log

このスクリプトは10秒おきにtopを実行し、そのデータをvirtualmemory.logファイルに記録します。

実行中の全プロセスの仮想メモリー使用量が、ログ・ファイルのVIRT列に記録されます。現在のステータスだけを確認するには、topと入力して[Shift]+[M]を押し、出力をメモリー使用量でソートします。これで、通常はJVMプロセスが出力の一番上に並びます。

virtualmemory.logのような記録を作成すると、JRockit JVMプロセスが実際に増加しているかどうかを確認し、増加の証拠としてOracleサポートに提示できるので便利です。

6.2.2.6 Oracleサポートへの連絡

この項に示されている解決策を試しても問題を解決できない場合は、第9章「サポートに関するオラクルへの連絡」の説明に従ってOracleサポートにご連絡ください。

6.3 スタック・オーバーフローのクラッシュ

スタック・オーバーフローのクラッシュは、JRockit JVMがスタック・オーバーフローのエラーを適切に処理できない場合に起こります。J2SE Javadocによると、java.lang.StackOverflowErrorが適切に処理されると、JVMが壊れているか、処理を続けるために必要なリソースが不足していることを示すためにjava.lang.VirtualMachineErrorがスローされます。

詳細は、次のJ2SE java.lang Javadocを参照してください。

JRockit JVMの.dumpファイルには、スローされたスタック・オーバーフロー・エラーの数に関する情報が記録されます。

6.3.1 スタック・オーバーフローのクラッシュの確認

スタック・オーバーフローが原因でJRockit JVMがクラッシュすると、テキスト・クラッシュ・ファイル(.dump)の一番上のあたりにError Message: Stack overflowと表示されます。その他にクラッシュ・ファイルのスタック・トレースが極度に長い場合や、スタック・トレースがまったくない場合も、このクラッシュを示している可能性があります。.dumpファイルにStackOverFlow: 2 StackOverFlowErrors occurredのように表示されている場合は、以前のスタック・オーバーフローの問題によりクラッシュがトリガーされた可能性があります。

6.3.2 スタック・オーバーフローのクラッシュのトラブルシューティング

この項では、スタック・オーバーフロー・エラーの解決方法をいくつか説明します。

6.3.2.1 アプリケーション・レベルでの変更

スタック・オーバーフロー・エラーの主な原因に、JRockit JVM のメモリー制限を超えたスタック領域を使用するようにアプリケーションが作成されていることがあります。

.dumpファイルでスタック・トレースを確認し、スタック領域の使用量を減らすようにJavaコードを変更できないか判断します。たとえば、アプリケーション・コードには再帰的なメソッド・コールが含まれる場合があります。再帰深度が深いとStackOverflowエラーが発生する可能性があります。

6.3.2.2 デフォルト・スタック・サイズの拡大

アプリケーションのスタック領域の使用量を変えるのが不可能な場合は、-Xssコマンドライン・オプションを使用してスレッドのスタック・サイズを変更できます。

6.3.2.3 スタック・オーバーフロー・エラーに対するJRockit JVMの抵抗力を強くする

-XX:+CheckStacksコマンドライン・オプションを使用すると、JRockit JVMのスタック・オーバーフロー・エラーに対する抵抗力を強化できます。これによって、通常はJVMがダンプしなくなり、java.lang.StackOverflowErrorをスローしなくなります。

-XX:+CheckStacksコマンドライン・オプションを指定すると、JVMがスタック上のページにアクセスするので、パフォーマンスがやや低下します。

6.3.2.4 Oracleサポートへの連絡

この項に示されている解決策を試しても問題を解決できない場合は、第9章「サポートに関するオラクルへの連絡」の説明に従ってOracleサポートにご連絡ください。

6.4 サポートされないLinux構成が原因のクラッシュ

JRockit JVMをLinuxで実行中にアプリケーションがクラッシュした場合は、スタック・トレースにクラッシュの理由が示されていても、JRockit JVMをサポート対象のLinux構成で実行しているか確認する必要があります。

次の処理を実行します。

この項に示されている解決策を試しても問題を解決できない場合は、第9章「サポートに関するオラクルへの連絡」の説明に従ってOracleサポートにご連絡ください。

6.5 JVMクラッシュ

JVMクラッシュは、JRockit JVMのプログラミング・エラーや、サードパーティ・ライブラリのコードのエラーによって発生する場合があります。

JVMクラッシュを特定およびトラブルシューティングすることで、JRockit JVMで問題が解決されるまでの一時的な回避策を見つけることができます。また、これにより、Oracleサポートが問題を迅速に特定し解決できるようになる場合があります。

JVMクラッシュの診断およびトラブルシューティングのプロセスは、クラッシュがコード生成またはガベージ・コレクションのどちらの場合に発生したかによって異なります。

6.5.1 コード生成中のクラッシュ

この項では、コード生成中に発生したJVMクラッシュを特定およびトラブルシューティングする方法について説明します。内容は次のとおりです。

6.5.1.1 コード生成クラッシュの原因である可能性が高いメソッドの特定

コード生成中にJVMがクラッシュした場合、その最も一般的な原因はミスコンパイルされたメソッドです。JRockit JVMがメソッドをミスコンパイルすると、JVMがクラッシュするか、メソッドが予測されている動作とは異なる動作をします。

テキスト・クラッシュ・ファイルは、クラッシュの時点でコンパイル中であったメソッドを特定します。メソッドは、.dumpファイルの先頭付近に存在する、Methodで始まる行で特定されます。

6.5.1.2 クラッシュの原因が最適化の問題かどうかの確認

JRockit JVMは、最適化コンパイラの問題が原因でメソッドをミスコンパイルした可能性があります。

最適化がクラッシュの原因かどうかを調べるには、-XnoOptコマンドライン・オプションを指定して最適化を無効にしてから、アプリケーションを再起動します。次に例を示します。

java -XnoOpt myApplication

JRockit JVMでアプリケーションが正常に実行されれば、クラッシュの原因はコードの最適化です。

6.5.1.3 問題のあるメソッドの最適化プロセスからの除外

JRockit JVMは、最適化コンパイラの問題が原因でメソッドをミスコンパイルした可能性があります。

グローバル最適化を無効にした後でJRockit JVMのクラッシュが停止した場合、(前の手順で特定した)問題のあるメソッドのみを、最適化ディレクティブを使用して最適化プロセスから除外できます。問題のあるメソッドを最適化しなければアプリケーションが正しく実行される場合は、この方法で問題を解決できます。

最適化ディレクティブの指定

制御ファイルでディレクティブを指定してから、-XX:OptFile=filenameコマンドライン・オプションを使用して制御ファイルを指定することで、JRockit JVMによるコードの最適化方法を制御できます。


注意:

-XX:OptFileは内部診断オプションです。したがってこれを使用するには、-XX:+UnlockDiagnosticVMOptionsをコマンドラインでも同様に、-XX:OptFileに付ける必要があります。

例6-1は、単一の最適化ディレクティブが含まれる制御ファイルが対象です。

例6-1 特定のメソッドに対するコンパイルの最適化を実行するためのディレクティブ

{
  match: [ "java/lang/FloatingDecimal.dtoa*", "java/lang/Object.*"],
  jit: { preset : opt, } ,
}

例6-1のディレクティブは、メソッドを最初にコンパイルするとき、matchキーワードで指定されたパターンに一致するメソッドを最適化するようにJRockit JVMに指示します。

例6-2 特定のメソッドに対する最適化を制限するためのディレクティブ

[
   {
      match: ["java/lang/FloatingDecimal.dtoa*", "java/lang/Object.*"],
      jit: { preset : opt, } ,
   },
   {
      match: "*",
      hotspot : { enable : false },
   }
]

例6-2のディレクティブは、java/lang/FloatingDecimal.dtoa*メソッドおよびjava/lang/Object.*メソッドのみに対する最適化(hotspot)を許可するように、JRockit JVMに指示を出します。

例6-3 メソッドのインライン化を制御するためのディレクティブ

{
   match: "java.lang.*",
   inline: ["+java.util.*", "-com.sun.*", "sun.*" ],
}

例6-3のディレクティブは、次の処理を行うようにJRockit JVMに指示を出します。

  • java.lang.*からjava.util.*へのメソッド・コールのインライン化の許可

  • java.lang.*からcom.sun.*へのメソッド・コールのインライン化の禁止

  • java.lang.*からsun.*へのメソッド・コールのインライン化の許可(可能な場合)

最適化ディレクティブの有効化

必要な最適化ディレクティブが含まれる制御ファイルを作成したら、-XX:OptFile=filenameコマンドライン・オプションを使用して制御ファイルのパス名を指定します。


注意:

-XX:OptFileは内部診断オプションです。したがってこれを使用するには、-XX:+UnlockDiagnosticVMOptionsをコマンドラインでも同様に、-XX:OptFileに付ける必要があります。

最適化ディレクティブの動作の確認

ディレクティブが予測どおりに機能しているか確認するには、-Xverbose:optコマンドライン・オプションを使用して出力をチェックします。最適化プロセスから除外したメソッドは出力に表示されません。-Xverbose:optの詳細は、『Oracle JRockitコマンドライン・リファレンス』を参照してください。

最適化ディレクティブを作成するためのガイドライン

  • ディレクティブが適用される対象のクラスおよびメソッドのパターンを指定するには、matchキーワードを使用します。指定する値は、単一のパターンが含まれる文字列か、パターンの配列のいずれかになります。

  • 最初にメソッドをコンパイルするときにJVMに実行させるタスクを指定するには、jitキーワードを使用します。

  • インライン化が必要なメソッド・コールを指定するには、inlineキーワードを使用します。

  • 個々のディレクティブを大カッコで囲みます。

  • 制御ファイルは複数のディレクティブを含むことが可能で、この場合は次の条件があります。

    • 隣り合ったディレクティブはカンマで区切る必要があります。

    • ディレクティブはすべて一続きで囲む必要があります。

6.5.1.4 外部のインストゥルメンテーション・ツールが原因かどうかのチェック

JVMクラッシュの原因がミスコンパイルされたメソッドではないと判断した場合は、使用中の外部のインストゥルメンテーション・ツール(JProbeまたはOptimizeItなど)が問題の原因でないか調査します。これらのツールはバイトコードを書き換えることがあり、これが予期しない動作を引き起こす場合があります。

問題の原因から外部のインストゥルメンテーション・ツールを除外するには、ツールを無効にしてからアプリケーションを実行します。

  • 外部ツールを無効にした後もJVMクラッシュが引き続き発生する場合、問題の原因はそのツールではありません。

  • アプリケーションが正常に実行される場合は、別のツールを使用するか、ツールを使わずに実行する必要があります。

6.5.1.5 Oracleサポートへの連絡

この項に示されている解決策を試しても問題を解決できない場合は、第9章「サポートに関するオラクルへの連絡」の説明に従ってOracleサポートにご連絡ください。

コード生成のクラッシュの場合は、次のデータをOracleサポートにご提供ください。

  • .coreまたは.mdmpファイル

  • .dumpファイル

  • 生成中だったメソッドが含まれる.classファイル

  • 生成中だったメソッドが含まれるクラスのソース・コード

6.5.2 ガベージ・コレクション中のクラッシュ

この項では、ガベージ・コレクション中に発生したJVMクラッシュを特定およびトラブルシューティングする方法について説明します。内容は次のとおりです。

6.5.2.1 ガベージ・コレクションのクラッシュの特定

テキスト・クラッシュ・ファイル(.dump)のスタック・トレースを調べることで、ガベージ・コレクションのクラッシュを特定できます。

スタック・トレースにガベージ・コレクション関数がある場合、またはクラッシュの原因となったスレッドがガベージ・コレクション・スレッドの1つである場合、クラッシュがガベージ・コレクション中に発生した可能性が最も高くなります。

スタック・トレース内のガベージ・コレクション関数は、mmgcycおよびocなどの接頭辞で識別されます。

6.5.2.2 JRockit JVMの最新のリリースへのアップグレード

JRockit JVMの最新リリースでは問題が修正されている場合があります。最新のリリースにアップグレードして、問題がまだ発生するかどうか確認します。

6.5.2.3 回避策の試行

ガベージ・コレクタを変更する

使用中のガベージ・コレクション・モードが問題の原因である場合、別のガベージ・コレクション・モードに変更すると回避できる可能性があります。たとえば、-Xgc:pausetimeを使用中の場合は、-Xgc:throughputへの切替えを試してください。ただし、ガベージ・コレクション・モードを変更すると、JRockit JVMから同じパフォーマンス・プロファイルを得られなくなります。

確定的ガベージ・コレクション・モードを使用している場合は、別のガベージ・コレクションに変更し、なおかつ確定的ガベージ・コレクションの機能をそのまま保持することはできません。このようなケースでは、ガベージ・コレクション・モードを変更するかわりに、Oracleサポートにご連絡ください。

詳細は、『Oracle JRockitパフォーマンス・チューニング・ガイド』を参照してください。

圧縮を無効にする

ヒープ圧縮のバグにより、ガベージ・コレクション中のクラッシュを引き起こす問題が発生する場合があります。-XXcompaction:enable=falseコマンドライン・オプションを使用すると圧縮を無効にできます。

ただし、-XXcompaction:enable=falseオプションを使用するとヒープが断片化するおそれがあるため、トラブルシューティングを行う場合にのみ使用してください。ヒープが断片化されすぎると、メモリー不足エラーが発生する可能性があります。

インライン化を無効にする

誤ったインライン化によってコードが壊れ、それが原因でガベージ・コレクタがライブ・オブジェクトを追跡できなくなる場合があります。「最適化ディレクティブの指定」の説明に従って最適化ディレクティブを使用すると、インライン化を無効にできます。

最適化コンパイラを使用する

最適化を行わないJITコンパイラが原因でコードが壊れ、ガベージ・コレクタがライブ・オブジェクトを追跡できなくなっているために、ガベージ・コレクションがクラッシュする場合があります。起動時に-XX:+PreOptコマンドを使用し、すべてに対して最適化コンパイラを使用するように設定してください。ただし、最適化コンパイラを使用すると、JVMの起動に時間がかかる場合があります。

6.5.2.4 Oracleサポートへの連絡

この項に示されている解決策を試しても問題を解決できない場合は、第9章「サポートに関するオラクルへの連絡」の説明に従ってOracleサポートにご連絡ください。Oracleサポートへのご連絡の際は、次の情報をご提供ください。

  • 完全な.coreファイルまたは.mdmpファイル(ガベージ・コレクションのクラッシュの場合)。この2つがないと、サポート・スタッフが問題を解決できません。.coreファイルまたは.mdmpファイルが、少なくともJavaヒープと同じくらいの大きさであることを確認してください。

  • クラッシュを再現できる場合は、そのクラッシュの再現に使用した手順。

  • 別のガベージ・コレクタを試した場合は、ガベージ・コレクタを変えることによって問題が軽減したか、あるいはどのガベージ・コレクタを使っても状況が変化しなかったか。

  • 試してみたすべての回避策の情報。