私はいくつかのJavaプロセスがあり、OOMエラーが発生したときに作成されたヒープダンプを管理しようとしています。
でOOMにヒープをダンプする場合
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp
jVMは、指定された/ tmpフォルダーに次の名前Java_pidXXXX.hprofのファイルを作成します(XXXXはプロセスのPIDです)。とにかく、PIDとDATEを使用してファイル名を作成する別の形式を指定する必要はありますか? 1時間グーグルで調べた後、myPrefix _ $、{pid}、 'date' .. etcを試しました。動作するのは2つだけです
\ tmpフォルダーが存在しない場合は作成されず、ヒープダンプも作成されません。
使用できる1つのアイデアは、OOMエラーにコマンドを追加することです
-XX:OnOutOfMemoryError="doSomething.sh %p"
しかし、「doSomething.sh」を展開する必要があるため、それを回避しようとしていました
コマンドラインの_-XX:HeapDumpPath
_は、既に発見したものよりも柔軟性がありません。つまり、次のいずれかを実行できます。
Java_pidXXX.hprof
_がそのディレクトリに作成されます。HotSpotソースの関連コードは heapDumper.cpp です。それを読んで、それは与えられたパス内の「マジックシーケンス」を探しません:
それでおしまい。それがディレクトリであるかどうかを判断する以外のパスの解析はありません。
追加できる唯一の柔軟性は、コマンドラインで名前を作成するときにシェルの機能を使用することです。そのため、_name_`date`.ext
_のようなものを使用するいくつかの例をWebで見ることができます。これは、_`date`
_を現在の日付once。つまり、ファイル名には、シェルがコマンドを処理してJVMを起動したときの日付/時刻が常に含まれます-ダンプが作成された日付/時刻ではありません。それで十分であれば、それを使用できます。現在、name_$(date).ext
構文を使用する方がより適切であると考えられていることに注意してください。
古いファイルを削除するために日付のみが必要な場合は、ファイルの最終変更時刻に基づいて削除できます(Unix/Linuxユーティリティfind
が役立ちます)。名前に日付を含める必要はありません。
$(date)
(または_`date`
_)トリックは、PIDに役立ちません。 _$$
_を使用する場合、シェルは現在のPIDを置き換えることもできますが、それはコマンドラインを処理するシェルのPIDであり、JVMプロセス自体ではありません。ただし、Shell exec
コマンドを使用してJavaアプリケーションを起動した場合、元のシェルと同じプロセスIDを受け取るため、実際に_$$
_を使用できますただし、exec
の後はスクリプトから実行されないことに注意してください。
したがって、@ apanginが彼の答えで提案したファイル名の動的な変更を試してみてください。ただし、OOMが実際に発生する前にファイル名を設定する必要があるため、ダンプ自体の時間を特定することはおそらく少し難しいことに注意してください。
HeapDumpPath
は管理可能なVMオプションです。これは、JMXを使用してランタイムで必要なものに設定できることを意味します。
String pid = ManagementFactory.getRuntimeMXBean().getName();
pid = pid.substring(0, pid.indexOf('@'));
String date = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
String fileName = "/tmp/heap_" + pid + "_" + date + ".dump";
HotSpotDiagnosticMXBean bean = ManagementFactory.newPlatformMXBeanProxy(
ManagementFactory.getPlatformMBeanServer(),
"com.Sun.management:type=HotSpotDiagnostic",
HotSpotDiagnosticMXBean.class);
bean.setVMOption("HeapDumpOnOutOfMemoryError", "true");
bean.setVMOption("HeapDumpPath", fileName);