JVMTM Tool Interface
バージョン1.2
|
JVM Tool Interfaceとは
JVMTM Tool Interface (JVM TI)は、開発ツールや監視ツールで使用されるプログラミング・インタフェースです。JavaTM仮想マシン(VM)で動作するアプリケーションの状態検査と実行制御の両方の機能を提供します。
JVM TIは、プロファイリング・ツール、デバッグ・ツール、監視ツール、スレッド分析ツール、カバレッジ分析ツールなど、VMの状態その他にアクセスする必要がある各種ツールのVMインタフェースとして機能します。
JVM TIは、JavaTM仮想マシンのすべての実装で使用できるとはかぎりません。
JVM TIは双方向のインタフェースです。JVM TIのクライアント(以下エージェントと呼ぶ)は、興味のある事象についてイベント経由で通知を受け取ることができます。JVM TIは、多数の関数を介して、アプリケーションのクエリーや制御を(イベントへの応答として、あるいはイベントから独立して)行えます。
個々のエージェントは同一のプロセスで実行され、検査対象のアプリケーションを実行する仮想マシンと直接通信します。この通信には、ネイティブ・インタフェース(JVM TI)が使用されます。ネイティブのインプロセス・インタフェースにより、ツール側への侵入は最小限に抑えながら、最大限の制御が可能になります。通常、エージェントは比較的コンパクトです。エージェントは、ターゲット・アプリケーションの通常の実行を妨げることなく、ツールの機能の大部分を実装する別のプロセスによって制御できます。
アーキテクチャ
ツールへの書込みは、JVM TIを使って直接行われるか、高度インタフェースを使って間接的に行われます。Java Platform Debugger Architectureには、JVM TIのほかに、より高いレベルのアウトプロセス・デバッガ・インタフェースも含まれています。多くのツールには、JVM TIよりも高いレベルのインタフェースの方が適しています。Java Platform Debugger Architectureの詳細については、Java Platform Debugger ArchitectureのWebサイトを参照してください。
エージェントの作成
エージェントの作成には、C言語の呼出し規則とC/C++の定義をサポートする任意のネイティブ言語を使用できます。
JVM TIを使用するために必要な関数、イベント、データ型、定数の定義は、インクルード・ファイルjvmti.h
で定義されます。これらの定義を使用するには、J2SETMインクルード・ディレクトリをインクルード・パスに追加し、
#include <jvmti.h>
をソース・コードに追加してください。
エージェントの配備
エージェントはプラットフォーム固有の方法で配備されますが、通常はそのプラットフォームでダイナミック・ライブラリに相当するものになります。たとえば、WindowsTMオペレーティング・システムの場合、エージェント・ライブラリは「ダイナミック・リンク・ライブラリ」(DLL)になります。SolarisTMオペレーティング環境の場合、エージェント・ライブラリは共有オブジェクト(.so
ファイル)になります。
VM起動時にエージェントを起動するには、コマンド行オプションを使ってエージェント・ライブラリの名前を指定します。実装によっては、ライブ段階でエージェントを起動するメカニズムをサポートしている可能性があります。その起動方法の詳細は、実装に固有となります。
静的リンク・エージェント(導入されたバージョン: 1.2.3)
ネイティブJVMTIエージェントは、VMと静的にリンクできます。ライブラリ・イメージとVMイメージとの結合方法は、実装に依存します。イメージがVMと結合されたエージェントLが静的リンクとして定義されるのは、そのエージェントがAgent_OnLoad_Lという名前の関数をエクスポートする場合のみです。
静的リンク・エージェントLからAgent_OnLoad_Lという名前の関数とAgent_OnLoadという名前の関数がエクスポートされた場合、Agent_OnLoad関数は無視されます。エージェントLが静的リンクの場合、Agent_OnLoad関数で規定されたのと同じ引数と期待される戻り値を指定して、Agent_OnLoad_L関数が呼び出されます。静的リンクのエージェントLは、同名のエージェントが動的にロードされるのを禁止します。
VMは、その実行中に動的エントリ・ポイントAgent_OnUnLoadが呼び出されていたのと同じポイントで、エージェントのAgent_OnUnload_L関数を呼び出します(そのような関数がエクスポートされていた場合)。静的にロードされたエージェントはアンロードできません。それでも、エージェントのシャットダウンに関する他のなんらかのタスクを行えるように、Agent_OnUnload_L関数が呼び出されます。静的リンク・エージェントLからAgent_OnUnLoad_Lという名前の関数とAgent_OnUnLoadという名前の関数がエクスポートされた場合、Agent_OnUnLoad関数は無視されます。
エージェントLが静的リンクの場合、Agent_OnUnLoad関数で規定されたのと同じ引数と期待される戻り値を指定して、Agent_OnUnLoad_L関数が呼び出されます。静的リンク・エージェントLからAgent_OnAttach_Lという名前の関数とAgent_OnAttachという名前の関数がエクスポートされた場合、Agent_OnAttach関数は無視されます。
エージェントのコマンド行オプション
以下の「コマンド行オプション」という語は、JNI呼び出しAPIのJNI_CreateJavaVM
関数において、JavaVMInitArgs
引数で指定されるオプションを意味します。
エージェントを適切にロードして実行するには、VMの起動時に次の2つのうちいずれかのコマンド行オプションが必要です。これらの引数は、エージェントを含むライブラリと、起動時に渡されるオプションの文字列を指定します。
-
-agentlib:
<agent-lib-name>=
<options>
-
-agentlib:
の後の名前は、ロードするライブラリの名前です。ライブラリの検索(その完全名と場所の両方)は、プラットフォーム固有の方法で進行します。通常、<agent-lib-name>はオペレーティング・システム固有のファイル名に展開されます。<options>は、起動時にエージェントに渡されます。たとえばオプション-agentlib:foo=opt1,opt2
が指定された場合、VMは、WindowsTMの下ではシステムPATH
から共有ライブラリfoo.dll
をロードしようとし、SolarisTMオペレーティング環境の下ではLD_LIBRARY_PATH
からlibfoo.so
をロードしようとします。エージェントのライブラリが実行可能ファイルに静的にリンクされている場合、実際のロード・タスクは発生しません。
-
-agentpath:
<path-to-agent>=
<options>
-
-agentpath:
の後ろには、ライブラリをロードする絶対パスを指定します。ライブラリ名の展開は行われません。<options>は、起動時にエージェントに渡されます。たとえば、オプション-agentpath:c:\myLibs\foo.dll=opt1,opt2
が指定された場合、VMは、共有ライブラリc:\myLibs\foo.dll
をロードしようとします。エージェントのライブラリが実行可能ファイルに静的にリンクされている場合、実際のロード・タスクは発生しません。
動的共有ライブラリ・エージェントの場合、ライブラリ内の起動ルーチンAgent_OnLoad
が呼び出されます。エージェントのライブラリが実行可能ファイルに静的にリンクされている場合、システムはAgent_OnLoad_<agent-lib-name>
エントリ・ポイント(<agent-lib-name>はエージェントのベース名)を呼び出そうとします。上の例(-agentpath:c:\myLibs\foo.dll=opt1,opt2
)の場合、システムはAgent_OnLoad_foo
起動ルーチンを見つけて呼び出そうとします。
バイト・コード・インストゥルメンテーション(bytecode instrumentation)のために必要な場合、ツール内でJavaプログラミング言語コードを使用しやすくするため、-agentlib:
または-agentpath:
を指定してロードされたライブラリから、JNIネイティブ・メソッド実装が検索されます。
エージェント・ライブラリは、その他のすべてのライブラリが検索されたあと検索されます。非エージェント・メソッドのネイティブ・メソッド実装を上書きまたは遮断するエージェントは、NativeMethodBindイベントを使用できます。
これらのスイッチは上記の処理のみを行います。VMやJVM TIの状態を変更することはありません。JVM TIやJVM TIの側面を有効にするためにコマンド行オプションを指定する必要はありません。これは、プログラム内で権限を使用して処理されます。
エージェントの起動
VMは、起動関数を呼び出すことで各エージェントを起動します。OnLoad
段階でエージェントを起動する場合は、関数Agent_OnLoad
(静的リンク・エージェントの場合はAgent_OnLoad_L
)が呼び出されます。ライブ段階でエージェントを起動する場合は、関数Agent_OnAttach
(静的リンク・エージェントの場合はAgent_OnAttach_L
)が呼び出されます。起動関数の呼出しは、エージェントごとに1回だけ行われます。
エージェントの起動(OnLoad段階)
OnLoad
段階でエージェントを起動する場合、そのエージェント・ライブラリは次のプロトタイプを持つ起動関数をエクスポートする必要があります。
JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
「L」という名前の静的リンク・エージェントの場合:
JNIEXPORT jint JNICALL
Agent_OnLoad_L(JavaVM *vm, char *options, void *reserved)
VMは、この関数を呼び出すことでエージェントを起動します。この呼出しはVM初期化の早い段階で行われるため、次のことが言えます。
-
システム・プロパティは、VMの起動で使用される前に設定できる
- すべての権限を使用できる(ただし、VMを構成する権限はこのときしか使用できない。詳細は「権限関数」セクションを参照)
- バイト・コードが実行されていない
- クラスがロードされていない
- オブジェクトが作成されていない
VMは、Agent_OnLoad
またはAgent_OnLoad_<agent-lib-name>
関数を、第2引数に<options>を指定して呼び出します。つまり、コマンド行オプションの例で言えば、Agent_OnLoad
のchar *options
引数に"opt1,opt2"
が渡されます。options
引数は修正UTF-8文字列としてエンコードされます。=<options>が指定されなかった場合は、長さゼロの文字列がoptions
に渡されます。options
文字列の存続期間は、Agent_OnLoad
またはAgent_OnLoad_<agent-lib-name>
呼出しの間です。この期間を超えて必要な場合は、文字列または文字列の一部をコピーする必要があります。Agent_OnLoad
が呼び出されてから復帰するまでの期間は、OnLoad段階と呼ばれます。OnLoad 段階ではVMは初期化されていないため、Agent_OnLoad
の内側で使用できる操作セットは限定されます(この時点で使用可能な機能については関数の説明を参照)。エージェントが安全に実行できるのは、オプションの処理や、SetEventCallbacks
でイベント・コールバックを設定する処理です。エージェントはVM初期化イベントを受け取った後(つまり、VMInitコールバックが呼び出された後)、初期化を完了させることができます。
原理の説明: 早い段階での起動が必要なのは、エージェントが目的の権限(その多くはVMの初期化前に設定する必要がある)を設定できるようにするためです。JVMDIでは-Xdebugコマンド行オプションによって、非常に粗粒度の権限制御機能が提供されていました。JVMPI実装では、様々なテクニックを使用して単一の「JVMPIオン」スイッチが提供されます。必要な権限とパフォーマンスへの影響のバランスを取るために必要な、細粒度の制御機能を提供できる適度なコマンド行オプションはありません。また、早い段階での起動は、エージェントが実行環境を制御できるようにする(ファイル・システムやシステム・プロパティを変更して機能をインストールできるようにする)ためにも必要です。
Agent_OnLoad
またはAgent_OnLoad_<agent-lib-name>
の戻り値は、エラーを示すために使用されます。ゼロ以外の値はすべてエラーを示しており、エラーが発生するとVMは終了します。
エージェントの起動(ライブ段階)
VMによっては、そのVM内でライブ段階でエージェントを起動するメカニズムをサポートしている可能性があります。そのサポート方法の詳細は、実装に固有となります。たとえば、あるツールでは、何らかのプラットフォーム固有のメカニズムや実装固有のAPIを使用することで、実行中のVMに接続して特定のエージェントの起動を要求する可能性があります。
ライブ段階でエージェントを起動する場合、そのエージェント・ライブラリは次のプロトタイプを持つ起動関数をエクスポートする必要があります。
JNIEXPORT jint JNICALL
Agent_OnAttach(JavaVM* vm, char *options, void *reserved)
「L」という名前の静的リンク・エージェントの場合:
JNIEXPORT jint JNICALL
Agent_OnAttach_L(JavaVM* vm, char *options, void *reserved)
VMは、この関数を呼び出すことでエージェントを起動します。これは、VMに接続されたスレッドのコンテキスト内で呼び出されます。第1引数の<vm>は、Java VMです。<options>引数はエージェントに提供される起動オプションです。<options>は修正UTF-8 文字列としてエンコードされます。起動オプションが指定されなかった場合は、長さゼロの文字列がoptions
に渡されます。options
文字列の存続期間は、Agent_OnAttach
またはAgent_OnAttach_<agent-lib-name>
呼出しの間です。この期間を超えて必要な場合は、文字列または文字列の一部をコピーする必要があります。
ライブ段階では権限の一部が使用できない可能性があります。
Agent_OnAttach
またはAgent_OnAttach_<agent-lib-name>
関数は、エージェントを初期化し、エラーが発生したかどうかを示す値をVMに返します。ゼロ以外の値はすべて、エラーを表します。エラーが発生してもVMは終了しません。代わりにVMは、そのエラーを無視するか、そのエラーを標準エラーに出力したりシステム・ログに記録したりするなど、何らかの実装固有のアクションを実行します。
エージェントの停止
ライブラリは、オプションで、次のプロトタイプを持つ停止関数をエクスポートできます。
JNIEXPORT void JNICALL
Agent_OnUnload(JavaVM *vm)
「L」という名前の静的リンク・エージェントの場合:
JNIEXPORT void JNICALL
Agent_OnUnload_L(JavaVM *vm)
この関数は、ライブラリのアンロードの直前にVMによって呼び出されます。ライブラリは(実行可能ファイルに静的にリンクされたライブラリでないかぎり)アンロードされます。この関数が呼び出されるのは、なんらかのプラットフォーム固有のメカニズムによってアンロードが発生した場合(このドキュメントではアンロード・メカニズムについては規定していない)、あるいはVMの終了(正常終了または起動エラーなどのVMエラーによるもの)によってライブラリが(実質的に)アンロードされる場合です。もちろん、制御されないシャットダウンはこの規則の例外です。この関数とVM終了イベントの違いに注意してください。VM終了イベントが送信されるためには、VMが少なくとも初期化のポイントまで実行済であり、かつVMDeathのコールバックを設定し、このイベントを有効化した有効なJVM TI環境が存在している必要があります。Agent_OnUnload
またはAgent_OnUnload_<agent-lib-name>
ではこれらの条件は一切不要です。また、その他の理由でライブラリがアンロードされる場合もこの関数が呼び出されます。VM終了イベントが送信される場合、それは、この関数が呼び出される前に送信されます(VMの終了によってこの関数が呼び出されると仮定した場合)。この関数を使えば、エージェントによって割り当てられたリソースをクリーンアップできます。
埋め込みVMや単にスクリプト内の深い場所で起動されるVMなどでは、コマンド行のアクセスや変更が常に可能であるとはかぎらないため、JAVA_TOOL_OPTIONS
変数が用意されています。これを使えば、そうした場合でもエージェントを起動できます。
環境変数などの名前付き文字列をサポートするプラットフォームでは、JAVA_TOOL_OPTIONS
変数がサポートされている可能性があります。この変数は、空白文字の境界で複数のオプションに分解されます。空白文字には、空白、タブ、復帰(CR)、復帰改行(NL)、垂直タブ、用紙送り(FF)などがあります。一連の空白文字は単一の空白文字と同等とみなされます。空白文字は、引用符で囲まれていないかぎり、オプションには含められません。引用方法は次のとおりです。
- 一重引用符の組('')に囲まれた、一重引用符を除くすべての文字は引用として囲まれる。
- 一重引用符の組の内部にある二重引用符には、特殊な意味はない。
- 二重引用符の組("")に囲まれた、二重引用符を除くすべての文字は引用として囲まれる。
- 二重引用符の組の内部にある一重引用符には、特殊な意味はない。
- 変数内の任意の場所を引用符で囲むことができる。
- 引用符で囲まれた空白文字には、特殊な意味はない。その他の文字と同様にオプションに含めることができ、区切り文字として機能しない。
- 引用符の組自体はオプションに含まれない。
JNI_CreateJavaVM
(JNI呼出しAPI内)は、JavaVMInitArgs
引数に指定されたオプションの先頭に、これらのオプションを付加します。セキュリティに問題がある場合、プラットフォームはこの機能を無効化することがあります。たとえばリファレンス実装は、UNIXシステムで実効ユーザーIDまたはグループIDが実際のIDと異なる場合に、この機能を無効化します。この機能はツールの初期化(具体的にはネイティブまたはJavaプログラミング言語エージェントの起動など)をサポートするためのものです。複数のツールがこの機能の使用を要求する可能性があるため、変数を上書きするのではなく、かわりに変数にオプションを追加すべきです。変数が処理されるのは、JNI呼出しAPIのVM作成呼出し時であるため、ランチャによって処理されるオプション(VM選択オプションなど)は処理されません。
環境
JVM TI仕様では、複数JVM TIエージェントの同時使用がサポートされています。各エージェントはそれぞれ独自のJVM TI環境を持ちます。つまり、JVM TIの状態はエージェントごとに異なります。ある環境を変更しても、他の環境はその影響を受けません。JVM TI環境の状態を次に示します。
エージェントのJVM TI状態はそれぞれ独立しているものの、エージェントはVMの共有状態を検査および変更するほか、実行先となるネイティブ環境も共有します。このため、あるエージェントが他のエージェントの結果を混乱させたり、他のエージェントの失敗の原因となる可能性があります。他のエージェントとの互換性のレベルを規定するのは、エージェント開発者の責任です。JVM TI実装には、エージェント間の破壊的な相互作用を回避する機能はありません。これらの問題が発生する可能性を減らす技法については、このドキュメントでは説明しません。
エージェントは、JNI呼び出しAPI関数GetEnvにインタフェースIDとしてJVM TIのバージョン情報を渡すことによって、JVM TI環境を作成します。JVM TI環境の作成と使用の詳細については、「JVM TI関数のアクセス」を参照してください。通常、JVM TI環境は、Agent_OnLoad
からGetEnv
を呼び出すことによって作成されます。
バイト・コード・インストゥルメンテーション
このインタフェースには、プロファイリングをサポートするインタフェースに通常期待されるいくつかのイベントが含まれていません。例として、オブジェクト割当てイベントやフル・スピードのメソッド・エントリ/終了イベントがあげられます。このインタフェースではかわりに、バイトコード・インストゥルメンテーション(ターゲット・プログラムを構成するJava仮想マシン・バイトコード命令を変更する機能)のサポートが提供されます。これらの変更の目的は通常、メソッドのコードに「イベント」を追加すること(たとえば、メソッドの先頭にMyProfiler.methodEntered()
呼出しを追加すること)です。変更は単に追加されるため、アプリケーションの状態や動作が変更されることはありません。挿入されるエージェント・コードは標準のバイトコードなので、VMをフル・スピードで実行できます(ターゲット・プログラムのみでなくインストゥルメンテーションも最適化される)。インストゥルメンテーションにバイトコード実行からの切替えが含まれていなければ、高コストの状態遷移が不要となります。その結果、イベントのパフォーマンスが高くなります。さらにこのアプローチは、完全な制御機能をエージェントに提供します。コードの「関心のある」部分(エンド・ユーザーのコードなど)にインストゥルメンテーションを限定可能で、しかも条件付きにできます。インストゥルメンテーションは、全体をJavaプログラミング言語コード内で実行することも、ネイティブ・エージェント内への呼出しを行うこともできます。インストゥルメンテーションは、単純にカウンタを保持することも、イベントの統計サンプリングを行うこともできます。
インストゥルメンテーションの挿入は、次の3とおりのうちのいずれかの方法で行います。
-
静的インストゥルメンテーション: クラス・ファイルは、たとえばインストゥルメンテーションを追加する目的で変更された
*.class
ファイルを含む複製ディレクトリを作成するなどの方法で、VMにロードされる前に計測されます。この方法はきわめて不自然であり、一般に、ロードされるクラス・ファイルの出所をエージェント側で知ることはできません。
-
ロード時のインストゥルメンテーション: クラス・ファイルがVMにロードされるとき、クラス・ファイルのrawバイトは、インストゥルメンテーション用としてエージェントに送信されます。クラスのロードによって発生した
ClassFileLoadHook
イベントが、この機能を提供します。このメカニズムは効率がよく、1回かぎりのインストゥルメンテーションに完全にアクセスできます。
-
動的インストゥルメンテーション: すでにロード済であり、場合によっては実行されている可能性もあるクラスが、変更されます。このオプション機能は、
RetransformClasses
関数を呼び出すことでトリガーされるClassFileLoadHook
イベントによって提供されます。クラスは複数回変更できるほか、元の状態に戻すこともできます。このメカニズムを使えば、実行中に変化するインストゥルメンテーションを実現できます。
このインタフェースに用意されたクラス変更機能は、インストゥルメンテーションのメカニズムを提供し(ClassFileLoadHook
イベントとRetransformClasses
関数)、開発時には修正しながらデバッグを続けていく(RedefineClasses
関数)ために用意されています。
依存関係が混乱しないように、特にコア・クラスを計測する場合は、注意が必要です。たとえば、各オブジェクト割当ての通知を受けるアプローチでは、Object
でコンストラクタを計測します。コンストラクタが最初は空であるとすると、このコンストラクタを次のように変更します。
public Object() {
MyProfiler.allocationTracker(this);
}
ただし、ClassFileLoadHook
イベントを使用してこの変更を行った場合、その影響が次のように典型的なVMに及ぶ可能性があります。最初に作成されるオブジェクトがコンストラクタを呼び出し、その結果、MyProfiler
のクラス・ロードが開始されます。次にオブジェクトが作成されますが、MyProfiler
はまだロードされていないので無限再帰に陥り、スタック・オーバーフローが発生します。これを改良するには、安全な時間になるまで追跡メソッドの呼出しを遅らせます。たとえば、VMInit
イベントのハンドラ内でtrackAllocations
を設定できます。
static boolean trackAllocations = false;
public Object() {
if (trackAllocations) {
MyProfiler.allocationTracker(this);
}
}
SetNativeMethodPrefix
を使えば、ラッパー・メソッドによるネイティブ・メソッドの計測が可能となります。
修正UTF-8の文字列エンコーディング
JVM TIは、修正UTF-8を使って文字列をエンコードします。これは、JNIが使用するのと同じエンコーディングです。修正UTF-8と標準のUTF-8との違いは、補助文字とnull文字の表現方法にあります。詳細については、JNI仕様の「変更後のUTF-8文字列」セクションを参照してください。
仕様のコンテキスト
このインタフェースはJava仮想マシンで実行されるアプリケーションの状態にアクセスするため、用語はJavaプラットフォームに関するものであり、特に言及している場合を除いてネイティブ・プラット・フォームに関するものではありません。例を示します。
- 「スレッド」はJavaプログラミング言語のスレッドを意味する。
- 「スタック・フレーム」はJava仮想マシンのスタック・フレームを意味する。
- 「クラス」はJavaプログラミング言語のクラスを意味する。
- 「ヒープ」はJava仮想マシンのヒープを意味する。
- 「モニター」はJavaプログラミング言語のオブジェクト・モニターを意味する。
Sun、Sun Microsystems、Sun のロゴ、Java、および JVM は、米国ならびにその他の国における Oracle Corporation およびその関連会社の登録商標です。
関数
関数のアクセス
ネイティブ・コードは、JVM TI関数を呼び出してJVM TI機能にアクセスします。JVM TI関数には、Java Native Interface (JNI)関数のアクセス時と同様に、インタフェース・ポインタを使ってアクセスします。JVM TIインタフェース・ポインタを環境ポインタと呼びます。
環境ポインタは、jvmtiEnv*
型の環境へのポインタです。環境には、JVM TI接続に関する情報があります。環境内の最初の値は、関数テーブルへのポインタです。関数テーブルは、JVM TI関数へのポインタの配列です。どの関数ポインタも配列内の事前に定義されたオフセットにあります。
C言語から使用される場合: 関数へのアクセス時に二重間接指定が使用されます。つまり環境ポインタは、コンテキストを提供するとともに、各関数呼出しの最初のパラメータになります。次に例を示します。
jvmtiEnv *jvmti;
...
jvmtiError err = (*jvmti)->GetLoadedClasses(jvmti, &class_count, &classes);
C++言語から使用される場合: 各関数はjvmtiEnv
のメンバー関数としてアクセスされ、環境ポインタが関数呼出しに渡されることはありません。次に例を示します。
jvmtiEnv *jvmti;
...
jvmtiError err = jvmti->GetLoadedClasses(&class_count, &classes);
特に指定しないかぎり、この仕様に含まれる例や宣言はすべて、C言語を使用しています。
JVM TI環境は、JNI呼び出しAPIのGetEnv
関数を使って取得できます。
jvmtiEnv *jvmti;
...
(*jvm)->GetEnv(jvm, &jvmti, JVMTI_VERSION_1_0);
GetEnv
を呼び出すたびに、新しいJVM TI接続、したがって新しいJVM TI環境が作成されます。GetEnv
のversion
引数は、JVM TIのバージョンでなければいけません。返された環境のバージョンが要求されたバージョンと異なることもありますが、返された環境は互換性があるはずです。GetEnv
からJNI_EVERSION
が返されるのは、互換性のあるバージョンが使用可能でない場合、JVM TIがサポートされていない場合、または現在のVM構成でJVM TIがサポートされていない場合です。特定のコンテキストでJVM TI環境を作成するためのその他のインタフェースが追加される可能性があります。各環境はそれぞれ独自の状態(必要なイベント、イベント処理関数、権限など)を持ちます。環境を解放するにはDisposeEnvironment
を使用します。したがって、スレッドごとに1つの環境が用意されるJNIと異なり、JVM TI環境は複数のスレッドにわたって動作し、動的に作成されます。
関数の戻り値
JVM TI関数は、常にjvmtiError
関数の戻り値からエラー・コードを返します。関数によっては、呼出し側の関数で指定されたポインタにより、これ以外の値を返すことも可能です。JVM TIの関数の中にはメモリーを割り当てるものがありますが、この場合はプログラム内でそのメモリーを明示的に解放しなければなりません。これについては、個々のJVM TI関数の説明に明記されています。空のリスト、配列、シーケンスなどは、NULL
として返されます。
JVM TI関数がエラーに遭遇した場合は(戻り値がJVMTI_ERROR_NONE
以外)、引数ポインタにより参照されるメモリー値は未定義です。しかし、メモリーおよびグローバル参照は何も割り当てられません。無効な入力のためにエラーが発生した場合、アクションは一切発生しません。
JNIオブジェクト参照の管理
JVM TI関数は、JNI参照(jobject
とjclass
)およびそれらの派生物(jthread
とjthreadGroup
)を使用してオブジェクトを識別します。JVM TI関数に渡す参照はグローバル参照、ローカル参照のどちらでもかまいませんが、強い参照でなければいけません。JVM TI関数から返される参照はすべてローカル参照です。これらのローカル参照はJVM TI呼出し時に作成されます。ローカル参照は、管理が必要なリソースです(JNIドキュメントを参照)。スレッドがネイティブ・コードから復帰する際に、すべてのローカル参照が解放されます。典型的なエージェント・スレッドを含む一部のスレッドは、決してネイティブ・コードから復帰しません。各スレッドは、明示的な管理を一切行わずに16個のローカル参照を作成できることが保証されています。限られた数のJVM TI呼出しを実行した後、ネイティブ・コードから復帰するようなスレッド(イベントを処理するスレッドなど)では、明示的な管理が不要であると判断される場合があります。ただし、長時間実行されるエージェント・スレッドでは、明示的なローカル参照管理が必要になります(通常はJNI関数PushLocalFrame
とPopLocalFrame
を使用)。逆に、ネイティブ・コードからの復帰後も参照を維持するには、それらをグローバル参照に変換する必要があります。これらの規則はjmethodID
とjfieldID
には適用されません。これらはjobject
ではないからです。
関数呼出しの必要条件
関数に、スレッドまたはVMを特定の状態(中断など)にするのはエージェントであると明示的に指定されていないかぎり、関数を実行するためにVMを一定の安全な状態にするのは、JVM TI実装になります。
例外と関数
JVM TI関数から例外がスローされることはありません。エラー状態は関数の戻り値として伝えられます。JVM TI関数が呼び出されている間、既存の例外状態はすべて維持されます。例外の処理については、JNI仕様のJava例外に関するセクションを参照してください。
関数の索引
メモリー管理
メモリー管理関数:
これらの関数は、JVM TI機能で使用されるメモリの割当て/割当て解除機能を備えており、エージェント用の作業メモリーを提供するために使用できます。JVM TIで管理されるメモリーは、他のメモリー割当てライブラリやメカニズムとは互換性がありません。
Allocate
jvmtiError
Allocate(jvmtiEnv* env,
jlong size,
unsigned char** mem_ptr)
JVM TIのアロケータを使用して、メモリーの領域を割り当てます。割り当てられたメモリーは、Deallocate
によって解放してください。
名前
|
型
|
説明
|
size | jlong |
割り当てるバイト数。
原理の説明: jlong はJVMDIとの互換性を実現するために使用される。
|
mem_ptr | unsigned char** |
戻ったとき、割り当てられたメモリーの先頭を指すポインタ。size がゼロの場合、NULL が返される。
エージェントはunsigned char* へのポインタを渡す。戻ったとき、unsigned char* は、サイズsize の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。 |
Deallocate
jvmtiError
Deallocate(jvmtiEnv* env,
unsigned char* mem)
JVM TIのアロケータを使用して、mem
を解放します。この関数は、JVM TIの関数によって割り当てられて返されたメモリー(Allocate
を使用して割り当てられたメモリーを含む)を解放するために使用します。割り当てられたすべてのメモリーを解除するまで、メモリーを再生することはできません。
名前
|
型
|
説明
|
mem | unsigned char * |
割り当てられたメモリーの先頭を指すポインタ。「On return, the elements are set」は無視してよい。
エージェントは、unsigned char の配列を渡す。配列の要素の値は無視される。戻ったとき、要素が設定されている。mem がNULL の場合、呼出しが無視される。
|
スレッド
スレッド関数:
スレッドの関数型:
スレッドの型:
スレッドのフラグおよび定数:
スレッド状態の取得
jvmtiError
GetThreadState(jvmtiEnv* env,
jthread thread,
jint* thread_state_ptr)
スレッドの状態を取得します。スレッドの状態は、以下の一連の質問に答えることでわかります。
答えは次のビット・ベクトルで表されます。
定数
|
値
|
説明
|
JVMTI_THREAD_STATE_ALIVE | 0x0001 |
スレッドは活動状態。スレッドが新規(起動していない)または終了した場合は、0。
|
JVMTI_THREAD_STATE_TERMINATED | 0x0002 |
スレッドは実行を完了した。
|
JVMTI_THREAD_STATE_RUNNABLE | 0x0004 |
スレッドは実行可能。
|
JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER | 0x0400 |
スレッドは同期ブロックまたはメソッドの入力を待機中。またはObject.wait() のあとで、同期ブロックまたはメソッドの再入力を待機中。
|
JVMTI_THREAD_STATE_WAITING | 0x0080 |
スレッドは待機中。
|
JVMTI_THREAD_STATE_WAITING_INDEFINITELY | 0x0010 |
スレッドはタイム・アウトなしで待機中。たとえば、Object.wait() 。
|
JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT | 0x0020 |
スレッドは、指定された最大待機時間で待機中。たとえば、Object.wait(long) 。
|
JVMTI_THREAD_STATE_SLEEPING | 0x0040 |
スレッドはスリープ中 - Thread.sleep(long) 。
|
JVMTI_THREAD_STATE_IN_OBJECT_WAIT | 0x0100 |
スレッドはオブジェクト・モニターを待機中 - Object.wait 。
|
JVMTI_THREAD_STATE_PARKED | 0x0200 |
スレッドは一時停止中。LockSupport.park 、LockSupport.parkUtil 、およびLockSupport.parkNanos 。
|
JVMTI_THREAD_STATE_SUSPENDED | 0x100000 |
スレッドが中断された。java.lang.Thread.suspend() またはJVM TIの中断関数(SuspendThread など)がスレッドで呼び出された。このビットが設定されている場合、他のビットはスレッドの中断前の状態を表します。
|
JVMTI_THREAD_STATE_INTERRUPTED | 0x200000 |
スレッド割込みが発生した。
|
JVMTI_THREAD_STATE_IN_NATIVE | 0x400000 |
スレッドはネイティブ・コード内にある。つまり、VMまたはJavaプログラミング言語コードに呼び戻されなかったネイティブ・メソッドが実行中。
このフラグは、VMでコンパイルされたJavaプログラミング言語コードの実行中、VMコードの実行中、VMサポート・コードの実行中は設定されない。JNIおよびJVM TI関数などのネイティブVMインタフェース関数は、VMコードとして実装することも可能。
|
JVMTI_THREAD_STATE_VENDOR_1 | 0x10000000 |
VMベンダーが定義する。
|
JVMTI_THREAD_STATE_VENDOR_2 | 0x20000000 |
VMベンダーが定義する。
|
JVMTI_THREAD_STATE_VENDOR_3 | 0x40000000 |
VMベンダーが定義する。
|
次の定義は、JVM TIスレッド状態をjava.lang.Thread.State
形式の状態に変換するために使用します。
定数
|
値
|
説明
|
JVMTI_JAVA_LANG_THREAD_STATE_MASK | JVMTI_THREAD_STATE_TERMINATED | JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_RUNNABLE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER | JVMTI_THREAD_STATE_WAITING | JVMTI_THREAD_STATE_WAITING_INDEFINITELY | JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT |
比較前に、この値で状態をマスクする
|
JVMTI_JAVA_LANG_THREAD_STATE_NEW | 0 |
java.lang.Thread.State.NEW
|
JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED | JVMTI_THREAD_STATE_TERMINATED |
java.lang.Thread.State.TERMINATED
|
JVMTI_JAVA_LANG_THREAD_STATE_RUNNABLE | JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_RUNNABLE |
java.lang.Thread.State.RUNNABLE
|
JVMTI_JAVA_LANG_THREAD_STATE_BLOCKED | JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER |
java.lang.Thread.State.BLOCKED
|
JVMTI_JAVA_LANG_THREAD_STATE_WAITING | JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_WAITING | JVMTI_THREAD_STATE_WAITING_INDEFINITELY |
java.lang.Thread.State.WAITING
|
JVMTI_JAVA_LANG_THREAD_STATE_TIMED_WAITING | JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_WAITING | JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT |
java.lang.Thread.State.TIMED_WAITING
|
規則
質問に対する回答は多くても1つですが、回答がないこともあります(回答が不明であるか、該当しないか、どの回答も正しくないため)。ある回答が設定されるのは、それを包含する回答が一致する場合のみです。つまり、次のいずれか1つ以上は設定できません。
-
JVMTI_THREAD_STATE_RUNNABLE
-
JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER
-
JVMTI_THREAD_STATE_WAITING
JVMTI_THREAD_STATE_ALIVE
が設定されている場合、J2SETM準拠実装では、以上のいずれかが常に設定されます。いずれかが設定されている場合は、包含する回答JVMTI_THREAD_STATE_ALIVE
が設定されます。以下のいずれか1つのみを
-
JVMTI_THREAD_STATE_WAITING_INDEFINITELY
-
JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT
設定できます(JVMTI_THREAD_STATE_WAITING
が設定されている場合、J2SETM準拠実装では、これらのいずれかが常に設定されます)。いずれかが設定されている場合、包含する回答JVMTI_THREAD_STATE_ALIVE
およびJVMTI_THREAD_STATE_WAITING
が設定されます。以下のいずれか1つのみを
-
JVMTI_THREAD_STATE_IN_OBJECT_WAIT
-
JVMTI_THREAD_STATE_PARKED
-
JVMTI_THREAD_STATE_SLEEPING
設定できます。いずれかが設定されている場合、包含する回答JVMTI_THREAD_STATE_ALIVE
およびJVMTI_THREAD_STATE_WAITING
が設定されます。またJVMTI_THREAD_STATE_SLEEPING
が設定されている場合は、JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT
が設定されます。状態Aが状態Bのメカニズムを使用して実装されている場合、この関数で返されるのは状態Aです。たとえばThread.sleep(long)
がObject.wait(long)
を使用して実装されている場合は、返されるのはJVMTI_THREAD_STATE_SLEEPING
のままです。以下は複数設定できます。
-
JVMTI_THREAD_STATE_SUSPENDED
-
JVMTI_THREAD_STATE_INTERRUPTED
-
JVMTI_THREAD_STATE_IN_NATIVE
ただし、いずれかが設定されると、JVMTI_THREAD_STATE_ALIVE
が設定されます。
そして、JVMTI_THREAD_STATE_TERMINATED
はJVMTI_THREAD_STATE_ALIVE
が設定されるまでは設定されません。
スレッド状態の表現は、将来のバージョンの仕様での拡張を前提に設計されています。スレッド状態の値を使用する際にはその点に留意すべきです(つまり、序数として使用すべきではない)。ほとんどのクエリーは単一のビットをテストすることで行えますが、switch文で状態ビットを使用する必要がある場合には、状態ビットを対象のビットでマスクすべきです。上で定義されていないビットはすべて、将来用として予約されたものです。現在の仕様に準拠したVMは、予約ビットをゼロに設定する必要があります。エージェントは予約ビットを無視すべきです。予約ビットは、ゼロであると仮定すべきではなく、したがって比較式に含めるべきではありません。
例
これから説明する値は、予約ビットとベンダー・ビットを除外しています。
synchronized
文でブロックされたスレッドの状態は次のようになります。
JVMTI_THREAD_STATE_ALIVE + JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER
開始していないスレッドの状態は次のようになります。
0
Object.wait(3000)
によるスレッドの状態は次のようになります。
JVMTI_THREAD_STATE_ALIVE + JVMTI_THREAD_STATE_WAITING +
JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT +
JVMTI_THREAD_STATE_MONITOR_WAITING
実行可能中に中断されたスレッドの状態は次のようになります。
JVMTI_THREAD_STATE_ALIVE + JVMTI_THREAD_STATE_RUNNABLE + JVMTI_THREAD_STATE_SUSPENDED
状態のテスト
ほとんどの場合、スレッドの状態は該当する状態に対応する1ビットをテストすれば判明します。たとえば、スレッドがスリープ状態かどうかをテストするコードは次のとおりです。
jint state;
jvmtiError err;
err = (*jvmti)->GetThreadState(jvmti, thread, &state);
if (err == JVMTI_ERROR_NONE) {
if (state & JVMTI_THREAD_STATE_SLEEPING) { ...
待機中(Object.wait
、一時停止中、またはスリープ中)の場合は、次のとおりです。
if (state & JVMTI_THREAD_STATE_WAITING) { ...
状態によっては、複数ビットをテストする必要があります。スレッドが開始していないかどうかをテストする場合などです。
if ((state & (JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_TERMINATED)) == 0) { ...
時間指定した場合としていない場合のObject.wait
を区別するには、次のようにします。
if (state & JVMTI_THREAD_STATE_IN_OBJECT_WAIT) {
if (state & JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT) {
printf("in Object.wait(long timeout)\n");
} else {
printf("in Object.wait()\n");
}
}
java.lang.Thread.State
との関係
java.lang.Thread.getState()
から返されるjava.lang.Thread.State
で示されるスレッドの状態は、この関数から返される情報のサブセットです。対応するjava.lang.Thread.State
は、指定された変換マスクを使用して決定できます。たとえば、次のコードはjava.lang.Thread.State
スレッド状態の名前を返します。
err = (*jvmti)->GetThreadState(jvmti, thread, &state);
abortOnError(err);
switch (state & JVMTI_JAVA_LANG_THREAD_STATE_MASK) {
case JVMTI_JAVA_LANG_THREAD_STATE_NEW:
return "NEW";
case JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED:
return "TERMINATED";
case JVMTI_JAVA_LANG_THREAD_STATE_RUNNABLE:
return "RUNNABLE";
case JVMTI_JAVA_LANG_THREAD_STATE_BLOCKED:
return "BLOCKED";
case JVMTI_JAVA_LANG_THREAD_STATE_WAITING:
return "WAITING";
case JVMTI_JAVA_LANG_THREAD_STATE_TIMED_WAITING:
return "TIMED_WAITING";
}
名前
|
型
|
説明
|
thread | jthread |
照会するスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
thread_state_ptr | jint* |
戻ったとき、スレッド状態フラグの定義に従って状態フラグをポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
現在のスレッドの取得
jvmtiError
GetCurrentThread(jvmtiEnv* env,
jthread* thread_ptr)
現在のスレッドを取得します。現在のスレッドとは、この関数を呼び出したJavaプログラミング言語スレッドのことです。
スレッドを引数に取るJVM TI関数のほとんどは、NULL
を現在のスレッドを意味するものとして受け入れます。
名前
|
型
|
説明
|
thread_ptr | jthread* |
戻ったとき、現在のスレッドをポイントする。
エージェントはjthread へのポインタを渡す。戻ったとき、jthread が設定されている。thread_ptr から返されるオブジェクトはJNIローカル参照であり、管理する必要がある。
|
すべてのスレッドの取得
jvmtiError
GetAllThreads(jvmtiEnv* env,
jint* threads_count_ptr,
jthread** threads_ptr)
すべてのライブ・スレッドを取得します。これらのスレッドは、Javaプログラミング言語のスレッド(つまりVMに接続されたスレッド)です。あるスレッドがライブ・スレッドになるのは、java.lang.Thread.isAlive()
がtrue
を返す場合(つまり、そのスレッドが起動後まだ終了していない場合)です。スレッドの領域はJVM TI環境のコンテキストによって決まりますが、それは通常、VMに接続されたすべてのスレッドになります。これにはJVM TIエージェント・スレッドも含まれます(RunAgentThread
を参照)。
名前
|
型
|
説明
|
threads_count_ptr | jint* |
戻ったとき、実行中のスレッドの数をポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
threads_ptr | jthread** |
戻ったとき、参照(実行中のスレッドごとに1つずつ)の配列をポイントする。
エージェントはjthread* へのポインタを渡す。戻ったとき、jthread* は、サイズ*threads_count_ptr の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。threads_ptr から返されるオブジェクトはJNIローカル参照であり、管理する必要がある。
|
スレッドの中断
jvmtiError
SuspendThread(jvmtiEnv* env,
jthread thread)
指定されたスレッドを中断します。呼出し側スレッドが指定されている場合、この関数は、ほかのスレッドがResumeThread
を呼び出すまで戻りません。スレッドが現在中断されている場合、この関数は何も行わず、エラーを返します。
名前
|
型
|
説明
|
thread | jthread |
中断するスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
スレッド・リストの中断
jvmtiError
SuspendThreadList(jvmtiEnv* env,
jint request_count,
const jthread* request_list,
jvmtiError* results)
request_list
配列に指定されたrequest_count
個のスレッドを中断します。スレッドの再開には、ResumeThreadList
またはResumeThread
を使用します。request_list
配列に呼出し側スレッドが指定されている場合、この関数は、ほかのスレッドによって再開されるまで戻りません。スレッドの中断中に発生したエラーは、この関数の戻り値ではなく、results
配列内に返されます。現在中断しているスレッドの状態は変わりません。
名前
|
型
|
説明
|
request_count | jint |
中断するスレッドの数。
|
request_list | const jthread* |
中断するスレッドのリスト。
エージェントはjthread のrequest_count 要素の配列を渡す。 |
results | jvmtiError* |
エージェントによって提供されたrequest_count 要素の配列。戻ったとき、対応するスレッドの中断のエラー・コードが入っている。スレッドがこの呼出しによって中断した場合、エラー・コードはJVMTI_ERROR_NONE になる。その他のエラー・コードは、SuspendThread に指定されたエラー・コード。
エージェントは、jvmtiError のrequest_count 要素を十分保持できる大きさの配列を渡す。配列の要素の値は無視される。戻ったとき、要素が設定されている。 |
スレッドの再開
jvmtiError
ResumeThread(jvmtiEnv* env,
jthread thread)
中断されているスレッドの実行を再開します。現在JVM TI中断関数(例、SuspendThread
)またはjava.lang.Thread.suspend()
によって中断されているスレッドの実行を再開します。その他のスレッドには影響はありません。
スレッド・リストの再開
jvmtiError
ResumeThreadList(jvmtiEnv* env,
jint request_count,
const jthread* request_list,
jvmtiError* results)
request_list
配列に指定されたrequest_count
個のスレッドを再開します。JVM TI中断関数(例: SuspendThreadList
)またはjava.lang.Thread.suspend()
経由で中断されたすべてのスレッドの実行が再開されます。
名前
|
型
|
説明
|
request_count | jint |
再開するスレッドの数。
|
request_list | const jthread* |
再開するスレッド。
エージェントはjthread のrequest_count 要素の配列を渡す。 |
results | jvmtiError* |
エージェントによって提供されたrequest_count 要素の配列。戻ったとき、対応するスレッドの再開のエラー・コードが入っている。スレッドがこの呼出しによって中断した場合、エラー・コードはJVMTI_ERROR_NONE になる。その他のエラー・コードは、ResumeThread に指定されたエラー・コード。
エージェントは、jvmtiError のrequest_count 要素を十分保持できる大きさの配列を渡す。配列の要素の値は無視される。戻ったとき、要素が設定されている。 |
スレッドの停止
jvmtiError
StopThread(jvmtiEnv* env,
jthread thread,
jobject exception)
指定された非同期の例外を指定されたスレッドに送ります(java.lang.Thread.stop
と同様)。通常、この関数は、指定されたスレッドを、例外ThreadDeath
のインスタンスを使って終了させるために使います。
スレッドの割込み
jvmtiError
InterruptThread(jvmtiEnv* env,
jthread thread)
指定されたスレッドに割り込みます(java.lang.Thread.interrupt
と同様)。
スレッド情報の取得
typedef struct {
char* name;
jint priority;
jboolean is_daemon;
jthreadGroup thread_group;
jobject context_class_loader;
} jvmtiThreadInfo;
jvmtiError
GetThreadInfo(jvmtiEnv* env,
jthread thread,
jvmtiThreadInfo* info_ptr)
スレッド情報を取得します。jvmtiThreadInfo
構造体のフィールドに、指定されたスレッドの詳細が入ります。
名前
|
型
|
説明
|
thread | jthread |
照会するスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
info_ptr | jvmtiThreadInfo* |
戻ったとき、指定されたスレッドについての情報が入っている。
コンテキスト・クラス・ローダーを認識しないJDK 1.1の実装の場合、context_class_loader フィールドはNULL。
エージェントはjvmtiThreadInfo へのポインタを渡す。戻ったとき、jvmtiThreadInfo が設定されている。jvmtiThreadInfo のname フィールドに返されるポインタは、新しく割り当てられた配列。この配列は、Deallocate を使って解放するべき。jvmtiThreadInfo のフィールドthread_group で返されるオブジェクトはJNIローカル参照であり、管理する必要がある。jvmtiThreadInfo のフィールドcontext_class_loader で返されるオブジェクトはJNIローカル参照であり、管理する必要がある。
|
所有モニター情報の取得
jvmtiError
GetOwnedMonitorInfo(jvmtiEnv* env,
jthread thread,
jint* owned_monitor_count_ptr,
jobject** owned_monitors_ptr)
指定されたスレッドが所有するモニターについての情報を取得します。
名前
|
型
|
説明
|
thread | jthread |
照会するスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
owned_monitor_count_ptr | jint* |
返されるモニターの数。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
owned_monitors_ptr | jobject** |
所有されるモニターの配列。
エージェントはjobject* へのポインタを渡す。戻ったとき、jobject* は、サイズ*owned_monitor_count_ptr の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。owned_monitors_ptr から返されるオブジェクトはJNIローカル参照であり、管理する必要がある。
|
所有モニターのスタックの深さ情報の取得
typedef struct {
jobject monitor;
jint stack_depth;
} jvmtiMonitorStackDepthInfo;
jvmtiError
GetOwnedMonitorStackDepthInfo(jvmtiEnv* env,
jthread thread,
jint* monitor_info_count_ptr,
jvmtiMonitorStackDepthInfo** monitor_info_ptr)
指定されたスレッドが所有するモニターに関する情報と、それらのモニターをロックしているスタック・フレームの深さを取得します。
フィールド
|
型
|
説明
|
monitor | jobject |
所有されるモニター。
|
stack_depth | jint |
スタックの深さ。スタック・フレーム関数で使用されるスタックの深さに対応している。つまり、0は現在のフレームを、1は現在のフレームを呼び出したフレームをそれぞれ表す。また、実装がスタックの深さを判断できない場合は - 1になる(JNIのMonitorEnter を使って取得されたモニターの場合など)。
|
名前
|
型
|
説明
|
thread | jthread |
照会するスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
monitor_info_count_ptr | jint* |
返されるモニターの数。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
monitor_info_ptr | jvmtiMonitorStackDepthInfo ** |
所有されるモニターの深さ情報の配列。
エージェントはjvmtiMonitorStackDepthInfo* へのポインタを渡す。戻ったとき、jvmtiMonitorStackDepthInfo* は、サイズ*monitor_info_count_ptr の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。jvmtiMonitorStackDepthInfo のフィールドmonitor で返されるオブジェクトはJNIローカル参照であり、管理する必要がある。
|
現在競合しているモニターの取得
jvmtiError
GetCurrentContendedMonitor(jvmtiEnv* env,
jthread thread,
jobject* monitor_ptr)
指定されたスレッドが、java.lang.Object.wait
を使ってオブジェクトのモニターに入るか、モニターを獲得し直すのを待機している場合に、そのオブジェクトを取得します。
名前
|
型
|
説明
|
thread | jthread |
照会するスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
monitor_ptr | jobject* |
戻ったとき、現在競合しているモニターが入っている。そのようなモニターがない場合はNULLが入っている。
エージェントはjobject へのポインタを渡す。戻ったとき、jobject が設定されている。monitor_ptr から返されるオブジェクトはJNIローカル参照であり、管理する必要がある。
|
エージェント起動関数
typedef void (JNICALL *jvmtiStartFunction)
(jvmtiEnv* jvmti_env,
JNIEnv* jni_env,
void* arg);
エージェントによって提供されるコールバック関数。この関数は、RunAgentThread で開始されるエージェント・スレッドのエントリ・ポイントになります。
|
エージェント・スレッドの実行
jvmtiError
RunAgentThread(jvmtiEnv* env,
jthread thread,
jvmtiStartFunction proc,
const void* arg,
jint priority)
指定されたネイティブ関数を使って、エージェント・スレッドの実行を開始します。パラメータarg
は起動関数 (proc
で指定)の単一の引数として転送されます。この関数により、java.lang.Thread
の特別なサブクラスやjava.lang.Runnable
の実装側をロードせずに、別のプロセスとの通信処理またはイベント処理用のエージェント・スレッドを作成できます。その代わり、作成されたスレッドは完全にネイティブ・コード内で実行できます。ただし、作成するスレッドには、java.lang.Thread
の新しく作成されたインスタンス(引数thread
によって参照される)が必要で、そのインスタンスにスレッドを関連付けます。スレッド・オブジェクトは、JNI呼出しで作成できます。
次に一般的なスレッド優先順位を参考として示します。
定数
|
値
|
説明
|
JVMTI_THREAD_MIN_PRIORITY | 1 |
いちばん低い優先順位
|
JVMTI_THREAD_NORM_PRIORITY | 5 |
中間の優先順位
|
JVMTI_THREAD_MAX_PRIORITY | 10 |
いちばん高い優先順位
|
新しいスレッドは、指定のpriority
で、デーモン・スレッドとして起動されます。有効な場合は、ThreadStart
イベントが送信されます。
スレッドの起動が完了しているため、このスレッドはこの関数が戻る際にライブ状態になっています。ただし、このスレッドがすぐに終了した場合は除きます。
このスレッドのスレッド・グループは無視されます。具体的には、このスレッドは、スレッド・グループに追加されず、Javaプログラミング言語、JVM TIのいずれのレベルでもスレッド・グループのクエリーには表示されません。
このスレッドは、Javaプログラミング言語のクエリーでは表示されませんが、GetAllThreads
やGetAllStackTraces
など、JVM TIのクエリーには含まれます。
proc
の実行時に、新しいスレッドはVMに接続されます。『Java Native Interface仕様』の「VMへの接続」を参照してください。
スレッド・ローカルな記憶領域の設定
jvmtiError
SetThreadLocalStorage(jvmtiEnv* env,
jthread thread,
const void* data)
VMは、個々の環境スレッド・ペアに関連付けられているポインタ値を格納します。このポインタ値をスレッド・ローカルな記憶領域と呼びます。この関数で設定されない場合、値はNULL
になります。エージェントは、スレッド固有の情報を格納するため、メモリーを割り当てることができます。スレッド・ローカルな記憶領域を設定することにより、GetThreadLocalStorage
を使ってアクセスできるようになります。
この関数は、JVM TIのスレッド・ローカルな記憶領域の値を設定するため、エージェントによって呼び出されます。JVM TIは、エージェントに対して、スレッドごとの情報を記録するために利用できる、ポインタ・サイズのスレッド・ローカルな記憶領域を提供します。
名前
|
型
|
説明
|
thread | jthread |
このスレッドを格納する。thread がNULL の場合、現在のスレッドが使用される。
|
data | const void * |
スレッド・ローカルな記憶領域に入力する値。
エージェントがポインタを渡す。data がNULL の場合、値はNULL に設定される。
|
スレッド・ローカルな記憶領域の取得
jvmtiError
GetThreadLocalStorage(jvmtiEnv* env,
jthread thread,
void** data_ptr)
JVM TIのスレッド・ローカルな記憶領域の値を取得するため、エージェントによって呼び出されます。
名前
|
型
|
説明
|
thread | jthread |
このスレッドから取得する。thread がNULL の場合、現在のスレッドが使用される。
|
data_ptr | void** |
スレッド・ローカルな記憶領域の値を返すポインタ。スレッド・ローカルな記憶領域がSetThreadLocalStorage で設定されていない場合、返されるポインタはNULL 。
|
スレッド・グループ
スレッド・グループ関数:
スレッド・グループの型:
トップ・レベルのスレッド・グループの取得
jvmtiError
GetTopThreadGroups(jvmtiEnv* env,
jint* group_count_ptr,
jthreadGroup** groups_ptr)
VM内のトップ・レベルの(親がない)スレッド・グループをすべて返します。
名前
|
型
|
説明
|
group_count_ptr | jint* |
戻ったとき、トップ・レベルのスレッド・グループの数をポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
groups_ptr | jthreadGroup** |
戻ったとき、トップ・レベルのスレッド・グループの配列を指すポインタを参照する。
エージェントはjthreadGroup* へのポインタを渡す。戻ったとき、jthreadGroup* は、サイズ*group_count_ptr の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。groups_ptr から返されるオブジェクトはJNIローカル参照であり、管理する必要がある。
|
スレッド・グループ情報の取得
typedef struct {
jthreadGroup parent;
char* name;
jint max_priority;
jboolean is_daemon;
} jvmtiThreadGroupInfo;
jvmtiError
GetThreadGroupInfo(jvmtiEnv* env,
jthreadGroup group,
jvmtiThreadGroupInfo* info_ptr)
スレッド・グループの情報を取得します。jvmtiThreadGroupInfo
構造体のフィールドに、指定されたスレッド・グループの詳細が入ります。
フィールド
|
型
|
説明
|
parent | jthreadGroup |
親スレッド・グループ。
|
name | char* |
スレッド・グループの名前。修正UTF-8文字列としてエンコードされる。
|
max_priority | jint |
このスレッド・グループの最高の優先順位。
|
is_daemon | jboolean |
デーモン・スレッド・グループかどうか。
|
名前
|
型
|
説明
|
group | jthreadGroup |
照会するスレッド・グループ。
|
info_ptr | jvmtiThreadGroupInfo* |
戻ったとき、指定されたスレッド・グループについての情報が入っている。
エージェントはjvmtiThreadGroupInfo へのポインタを渡す。戻ったとき、jvmtiThreadGroupInfo が設定されている。jvmtiThreadGroupInfo のフィールドparent で返されるオブジェクトはJNIローカル参照であり、管理する必要がある。jvmtiThreadGroupInfo のname フィールドに返されるポインタは、新しく割り当てられた配列。この配列は、Deallocate を使って解放するべき。 |
子スレッド・グループの取得
jvmtiError
GetThreadGroupChildren(jvmtiEnv* env,
jthreadGroup group,
jint* thread_count_ptr,
jthread** threads_ptr,
jint* group_count_ptr,
jthreadGroup** groups_ptr)
このスレッド・グループ内のライブ・スレッドとアクティブなサブグループを取得します。
名前
|
型
|
説明
|
group | jthreadGroup |
照会するグループ。
|
thread_count_ptr | jint* |
戻ったとき、このスレッド・グループ内のライブ・スレッドの数をポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
threads_ptr | jthread** |
戻ったとき、このスレッド・グループ内のライブ・スレッドの配列をポイントする。
エージェントはjthread* へのポインタを渡す。戻ったとき、jthread* は、サイズ*thread_count_ptr の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。threads_ptr から返されるオブジェクトはJNIローカル参照であり、管理する必要がある。
|
group_count_ptr | jint* |
戻ったとき、アクティブな子スレッド・グループの数をポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
groups_ptr | jthreadGroup** |
戻ったとき、アクティブな子スレッド・グループの配列をポイントする。
エージェントはjthreadGroup* へのポインタを渡す。戻ったとき、jthreadGroup* は、サイズ*group_count_ptr の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。groups_ptr から返されるオブジェクトはJNIローカル参照であり、管理する必要がある。
|
スタック・フレーム
スタック・フレーム関数:
スタック・フレームの型:
これらの関数は、スレッドのスタックに関する情報を提供します。スタック・フレームは、深さで参照されます。深さゼロのフレームが現在のフレームです。
スタック・フレームについては、Java(tm)仮想マシン仕様のセクション3.6に記載されています。つまり、これらのフレームは、ネイティブ・メソッドを含むメソッドの呼出しに対応しているが、プラットフォーム固有のフレームやVM内部のフレームには対応していません。
JVM TI実装はメソッド呼び出しを使用してスレッドを起動する可能性があるので、対応するフレームがそれらの関数によって提供される情報として、スタック内に含まれる可能性があります。つまり、main()
やrun()
よりも深い位置に表示されるフレームが存在する可能性があります。ただしこの表現は、スタック・フレームやスタックの深さを使用するすべてのJVM TI機能の間で一貫している必要があります。
スタック・フレーム情報構造体
スタック・フレームに関する情報は次の構造体で戻されます。
typedef struct {
jmethodID method;
jlocation location;
} jvmtiFrameInfo;
フィールド
|
型
|
説明
|
method | jmethodID |
このフレーム内で実行されているメソッド。
|
location | jlocation |
このフレーム内で実行されている命令のインデックス。フレームがネイティブ・メソッドを実行している場合は-1 。
|
スタック情報構造体
スタック・フレーム・セットに関する情報は次の構造体で戻されます。
typedef struct {
jthread thread;
jint state;
jvmtiFrameInfo* frame_buffer;
jint frame_count;
} jvmtiStackInfo;
フィールド
|
型
|
説明
|
thread | jthread |
戻ったとき、トレースされたスレッド。
|
state | jint |
戻ったとき、スレッドの状態。GetThreadState を参照。
|
frame_buffer | jvmtiFrameInfo * |
戻ったとき、このエージェントによって割り当てられたバッファに、スタック・フレーム情報が入っている。
|
frame_count | jint |
戻ったとき、レコード数がframe_buffer に入っている。これはmin(max_frame_count , stackDepth)になる。
|
スタック・トレースの取得
jvmtiError
GetStackTrace(jvmtiEnv* env,
jthread thread,
jint start_depth,
jint max_frame_count,
jvmtiFrameInfo* frame_buffer,
jint* count_ptr)
あるスレッドのスタックに関する情報を取得します。max_frame_count
がスタックの深さより小さい場合、max_frame_count
のいちばん上のフレームが返され、それ以外の場合はスタック全体が返されます。最後に呼び出されたフレームである最上位フレームが、返されるバッファの先頭になります。
次の例では、いちばん上のフレームから5つめまでのフレームが返されます。さらに、フレームがある場合は、現在実行しているメソッドの名前が出力されます。
jvmtiFrameInfo frames[5];
jint count;
jvmtiError err;
err = (*jvmti)->GetStackTrace(jvmti, aThread, 0, 5,
frames, &count);
if (err == JVMTI_ERROR_NONE && count >= 1) {
char *methodName;
err = (*jvmti)->GetMethodName(jvmti, frames[0].method,
&methodName, NULL, NULL);
if (err == JVMTI_ERROR_NONE) {
printf("Executing method: %s", methodName);
}
}
thread
は、中断することなく、この関数を呼び出すことができます。
位置と行番号のマッピングには、GetLineNumberTable
関数を使用できます。このマッピングは、遅延してもかまいません。
名前
|
型
|
説明
|
thread | jthread |
このスレッドのスタック・トレースをフェッチする。thread がNULL の場合、現在のスレッドが使用される。
|
start_depth | jint |
フレームの取得をこの深さから開始する。負でない場合は現在のフレームからカウントし、最初に取得されるフレームは深さstart_depth になる。たとえば、0の場合は現在のフレームから開始し、1の場合は現在のフレームの呼出し元から開始し、2の場合は現在のフレームの呼出し元の呼出し元から開始する、といった具合になる。負の場合、もっとも古いフレームの下からカウントし、最初に取得されるフレームは深さstackDepth + start_depth になる(stackDepthはスタックのフレーム数)。たとえば、マイナス1の場合はもっとも古いフレームのみが取得され、マイナス2の場合はもっとも古いフレームから呼び出されたフレームから開始する。
|
max_frame_count | jint |
取得するjvmtiFrameInfo レコードの最大数。
|
frame_buffer | jvmtiFrameInfo * |
戻ったとき、このエージェントによって割り当てられたバッファに、スタック・フレーム情報が入っている。
エージェントは、jvmtiFrameInfo のmax_frame_count 要素を十分保持できる大きさの配列を渡す。配列の要素の値は無視される。戻ったとき、要素の*count_ptr が設定される。 |
count_ptr | jint* |
戻ったとき、情報を入力されるレコードの数をポイントする。start_depth が負の数でない場合、min(max_frame_count , stackDepth - start_depth )。start_depth が負の数の場合、min(max_frame_count , -start_depth )。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
すべてのスタック・トレースの取得
jvmtiError
GetAllStackTraces(jvmtiEnv* env,
jint max_frame_count,
jvmtiStackInfo** stack_info_ptr,
jint* thread_count_ptr)
すべてのライブ・スレッドのスタックに関する情報を取得します(エージェント・スレッドを含む)。max_frame_count
がスタックの深さより小さい場合、そのスレッドについてmax_frame_count
のいちばん上のフレームが返され、それ以外の場合はスタック全体が返されます。最後に呼び出されたフレームである最上位フレームが、返されるバッファの先頭になります。
すべてのスタックは、同時に収集されます。つまり、あるスレッドのサンプリングと次のスレッドのサンプリングとの間には、スレッドの状態またはスタックに変更は発生しません。スレッドを中断する必要はありません。
jvmtiStackInfo *stack_info;
jint thread_count;
int ti;
jvmtiError err;
err = (*jvmti)->GetAllStackTraces(jvmti, MAX_FRAMES, &stack_info, &thread_count);
if (err != JVMTI_ERROR_NONE) {
...
}
for (ti = 0; ti < thread_count; ++ti) {
jvmtiStackInfo *infop = &stack_info[ti];
jthread thread = infop->thread;
jint state = infop->state;
jvmtiFrameInfo *frames = infop->frame_buffer;
int fi;
myThreadAndStatePrinter(thread, state);
for (fi = 0; fi < infop->frame_count; fi++) {
myFramePrinter(frames[fi].method, frames[fi].location);
}
}
/* this one Deallocate call frees all data allocated by GetAllStackTraces */
err = (*jvmti)->Deallocate(jvmti, stack_info);
スレッド・リストのスタック・トレースの取得
jvmtiError
GetThreadListStackTraces(jvmtiEnv* env,
jint thread_count,
const jthread* thread_list,
jint max_frame_count,
jvmtiStackInfo** stack_info_ptr)
指定されたスレッドのスタックに関する情報を取得します。max_frame_count
がスタックの深さより小さい場合、そのスレッドについてmax_frame_count
のいちばん上のフレームが返され、それ以外の場合はスタック全体が返されます。最後に呼び出されたフレームである最上位フレームが、返されるバッファの先頭になります。
すべてのスタックは、同時に収集されます。つまり、あるスレッドのサンプリングと次のスレッドのサンプリングとの間には、スレッドの状態またはスタックに変更は発生しません。スレッドを中断する必要はありません。
スレッドがまだ起動されていないか、スタック情報が収集される前にスレッドが終了した場合は、長さ0のスタック(jvmtiStackInfo.frame_count
が0)が返されるため、スレッドjvmtiStackInfo.state
をチェックできます。
例は、同様な関数GetAllStackTraces
を参照してください。
フレーム・カウントの取得
jvmtiError
GetFrameCount(jvmtiEnv* env,
jthread thread,
jint* count_ptr)
指定されたスレッドの呼出しスタックに現在入っているフレームの数を取得します。
アクティブにバイト・コードを実行しているスレッド(現在のスレッドではなく、中断されていないスレッドなど)のためにこの関数が呼び出された場合、一時的な情報が返されます。
名前
|
型
|
説明
|
thread | jthread |
照会するスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
count_ptr | jint* |
戻ったとき、呼出しスタック内のフレームの数をポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
フレームのポップ
jvmtiError
PopFrame(jvmtiEnv* env,
jthread thread)
thread
スタックの現在のフレームをポップします。フレームをポップすると、直前のフレームに戻ります。スレッドが再開されると、スレッドの実行状態は、メソッドが呼び出される直前の状態にリセットされます。Java(tm)仮想マシン仕様の用語で説明すると、次のようになります。
- 現在のフレームが破棄され、以前のフレームが現在のフレームになる
- オペランド・スタックは回復します。引数が再度追加され、呼出しが
invokestatic
ではなかった場合、objectref
も再度追加されます。
- Java仮想マシンのPCが呼出し命令の操作コード(opcode)へ回復する
ただし、呼出し先のメソッドで発生した引数の変更内容は保持されます。実行を続行すると、最初の実行指示が呼び出しとなります。
PopFrame
の呼び出しとスレッドの再開の間、スタックの状態は未定義です。最初のフレームよりも前にフレームをポップするには、次の3つの手順を繰り返す必要があります。
- イベントを通じてスレッドを中断する(ステップ、ブレークポイントなど)
PopFrame
を呼び出す
- スレッドを再開する
被呼出しメソッドを呼び出すことによって獲得されたロック(これがsynchronized
メソッドの場合)と、被呼出しメソッド内のsynchronized
ブロックに入ることによって獲得されたロックは解放されます。注: これは、ネイティブ・ロックやjava.util.concurrent.locks
ロックには適用されません。
最終的に、ブロックは実行されません。
グローバル状態への変更には対応しないので、変更は行われません。
指定されたスレッドは中断されていなければいけません。これは、そのスレッドが現在のスレッドであってはいけないことを意味します。
被呼出しメソッドと呼出し側のメソッドのどちらも、非ネイティブのJavaプログラミング言語のメソッドとします。
この関数は、JVM TIイベントを生成しません。
名前
|
型
|
説明
|
thread | jthread |
ポップする現在のフレームのスレッド。
|
フレームの位置の取得
jvmtiError
GetFrameLocation(jvmtiEnv* env,
jthread thread,
jint depth,
jmethodID* method_ptr,
jlocation* location_ptr)
Javaプログラミング言語のフレームについて、現在実行中の命令の位置を返します。
名前
|
型
|
説明
|
thread | jthread |
照会するフレームのスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
depth | jint |
照会するフレームの深さ。
|
method_ptr | jmethodID* |
戻ったとき、現在の位置のメソッドをポイントする。
エージェントはjmethodID へのポインタを渡す。戻ったとき、jmethodID が設定されている。 |
location_ptr | jlocation* |
戻ったとき、現在実行中の命令のインデックスをポイントする。フレームがネイティブ・メソッドを実行している場合は-1 に設定される。
エージェントはjlocation へのポインタを渡す。戻ったとき、jlocation が設定されている。 |
フレームのポップの通知
jvmtiError
NotifyFramePop(jvmtiEnv* env,
jthread thread,
jint depth)
深さdepth
のフレームがスタックからポップされたとき、FramePop
イベントを生成します。詳細は、FramePop
イベントの説明を参照してください。非ネイティブJavaプログラミング言語のメソッドに対応するフレームだけが通知を受信できます。
指定したスレッドは現在のスレッドであるか、スレッドが中断したかのどちらかです。
名前
|
型
|
説明
|
thread | jthread |
フレームのポップ・イベントが生成されるフレームのスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
depth | jint |
フレームのポップ・イベントが生成されるフレームの深さ。
|
早期復帰の強制
早期復帰の強制の関数:
これらの関数を使うと、エージェントは、実行中の任意のポイントでの復帰をメソッドに強制できます。早期復帰するメソッドを被呼出しメソッドと呼びます。被呼出しメソッドは、Java(tm)仮想マシン仕様のセクション3.6に定義されているとおり、関数の呼出し時に、指定されたスレッドの現在のメソッドになります。
指定されたスレッドは、中断されているか、現在のスレッドでなければいけません。メソッドの復帰は、Javaプログラミング言語のコードの実行がこのスレッド上で再開されたときに行われます。これらの関数のいずれかを呼び出してからスレッドの実行が再開されるまでの間のスタックの状態は未定義です。
被呼出しメソッドでは、これ以上の命令は実行されません。特に、最終的にブロックは実行されません。注: これにより、アプリケーション内で整合性のない状態が発生することがあります。
被呼出しメソッドを呼び出すことによって獲得されたロック(これがsynchronized
メソッドの場合)と、被呼出しメソッド内のsynchronized
ブロックに入ることによって獲得されたロックは解放されます。注: これは、ネイティブ・ロックやjava.util.concurrent.locks
ロックには適用されません。
通常復帰の場合と同様に、MethodExit
などのイベントが生成されます。
被呼出しメソッドは、非ネイティブのJavaプログラミング言語のメソッドとします。スタック上にフレームが1つだけある状態でスレッドへの強制復帰を行なった場合、スレッドが再開時に終了します。
早期復帰の強制 - オブジェクト型
jvmtiError
ForceEarlyReturnObject(jvmtiEnv* env,
jthread thread,
jobject value)
この関数を使うと、結果の型がObject
またはObject
のサブクラスであるメソッドから復帰できます。
名前
|
型
|
説明
|
thread | jthread |
現在のフレームが早期復帰するスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
value | jobject |
被呼出しフレームの戻り値。オブジェクトまたはNULL 。
|
早期復帰の強制 - 整数型
jvmtiError
ForceEarlyReturnInt(jvmtiEnv* env,
jthread thread,
jint value)
この関数を使うと、結果の型がint
、short
、char
、byte
、boolean
のいずれかであるメソッドから復帰できます。
名前
|
型
|
説明
|
thread | jthread |
現在のフレームが早期復帰するスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
value | jint |
被呼出しフレームの戻り値。
|
早期復帰の強制 - 長整数型
jvmtiError
ForceEarlyReturnLong(jvmtiEnv* env,
jthread thread,
jlong value)
この関数を使うと、結果の型がlong
であるメソッドから復帰できます。
名前
|
型
|
説明
|
thread | jthread |
現在のフレームが早期復帰するスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
value | jlong |
被呼出しフレームの戻り値。
|
早期復帰の強制 - 浮動小数点数型
jvmtiError
ForceEarlyReturnFloat(jvmtiEnv* env,
jthread thread,
jfloat value)
この関数を使うと、結果の型がfloat
であるメソッドから復帰できます。
名前
|
型
|
説明
|
thread | jthread |
現在のフレームが早期復帰するスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
value | jfloat |
被呼出しフレームの戻り値。
|
早期復帰の強制 - 倍精度浮動小数点数型
jvmtiError
ForceEarlyReturnDouble(jvmtiEnv* env,
jthread thread,
jdouble value)
この関数を使うと、結果の型がdouble
であるメソッドから復帰できます。
名前
|
型
|
説明
|
thread | jthread |
現在のフレームが早期復帰するスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
value | jdouble |
被呼出しフレームの戻り値。
|
早期復帰の強制 - void型
jvmtiError
ForceEarlyReturnVoid(jvmtiEnv* env,
jthread thread)
この関数を使うと、結果の型を持たないメソッドから復帰できます。つまり、被呼出しメソッドがvoid
と宣言されていなければいけません。
名前
|
型
|
説明
|
thread | jthread |
現在のフレームが早期復帰するスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
ヒープ
ヒープ関数:
ヒープの関数型:
ヒープの型:
ヒープのフラグおよび定数:
これらの関数は、ヒープの分析に使用されます。ヒープ内のオブジェクトの表示、これらのオブジェクトへのタグ付けなどの機能があります。
タグは、オブジェクトに関連付けられる値です。タグは、エージェントにより、SetTag
関数を使用して明示的に設定されます。または、jvmtiHeapIterationCallback
などのコールバック関数によって設定されます。
タグは環境に対してローカルです。つまり、ある環境のタグを別の環境で表示することはできません。
jlong
値であるタグを使えば、オブジェクトを単純にマークしたり、詳細情報へのポインタを格納したりできます。タグ付けされていないオブジェクトのタグはゼロになります。タグをゼロに設定すると、オブジェクトのタグ付けが解除されます。
ヒープ・コールバック関数
ヒープ関数は、ヒープ内での反復処理とオブジェクト参照の再帰的な追跡を行い、エージェントが指定したコールバック関数を使って情報提供を行います。
これらのヒープ・コールバック関数は次の制限に準拠する必要があります。これらのコールバックはJNI関数を使用してはいけません。これらのコールバックは、コールバック安全な関数(そのような使用を明確に許可している関数)以外のJVM TI関数を使用してはいけません(rawモニター関数、メモリー管理関数、環境ローカル・ストレージ関数を参照)。
実装は、内部スレッド上または反復関数を呼び出したスレッド上で、コールバックを呼び出せます。ヒープ・コールバックはシングル・スレッドです。一度に呼び出されるコールバックの数は最大1個になります。
ヒープ・フィルタ・フラグを使うと、オブジェクトまたはそのクラスのタグの状態に基づいて報告を行わないようにすることができます。フラグが設定されていない場合(jint
がゼロの場合)、オブジェクトのフィルタ・リングは行われません。
定数
|
値
|
説明
|
JVMTI_HEAP_FILTER_TAGGED | 0x4 |
タグ付きのオブジェクトをフィルタ・リングする。タグの付いたオブジェクトが除外される。
|
JVMTI_HEAP_FILTER_UNTAGGED | 0x8 |
タグなしのオブジェクトをフィルタ・リングする。タグの付いていないオブジェクトが除外される。
|
JVMTI_HEAP_FILTER_CLASS_TAGGED | 0x10 |
タグ付きのクラスを持つオブジェクトをフィルタ・リングする。タグの付いたクラスのオブジェクトが除外される。
|
JVMTI_HEAP_FILTER_CLASS_UNTAGGED | 0x20 |
タグなしのクラスを持つオブジェクトをフィルタ・リングする。タグの付いていないクラスのオブジェクトが除外される。
|
ヒープ・コールバックによって返されるヒープ・ビジット制御フラグを使うと、反復処理を中止できます。また、ヒープ参照コールバックは、トラバース対象となる参照のグラフを取り除くために使うこともできます(JVMTI_VISIT_OBJECTS
を設定しない)。
定数
|
値
|
説明
|
JVMTI_VISIT_OBJECTS | 0x100 |
あるオブジェクトをビジットする際にこのコールバックがFollowReferences によって起動されたものであった場合、そのオブジェクトの参照をトラバースする。それ以外の場合は無視される。
|
JVMTI_VISIT_ABORT | 0x8000 |
反復処理を中止。ほかのすべてのビットを無視する。
|
ヒープ参照の列挙は、報告対象の参照の種類を記述する目的で、ヒープ参照コールバックとプリミティブ・フィールド・コールバックによって提供されます。
定数
|
値
|
説明
|
JVMTI_HEAP_REFERENCE_CLASS | 1 |
オブジェクトからそのクラスへの参照。
|
JVMTI_HEAP_REFERENCE_FIELD | 2 |
オブジェクトから、そのオブジェクトのいずれかのインスタンス・フィールド値への参照。
|
JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT | 3 |
配列から、その配列のいずれかの要素への参照。
|
JVMTI_HEAP_REFERENCE_CLASS_LOADER | 4 |
クラスからそのクラス・ローダーへの参照。
|
JVMTI_HEAP_REFERENCE_SIGNERS | 5 |
クラスからその署名者の配列への参照。
|
JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN | 6 |
クラスからその保護ドメインへの参照。
|
JVMTI_HEAP_REFERENCE_INTERFACE | 7 |
クラスから、そのクラスのいずれかのインタフェースへの参照。注: インタフェースは定数プール参照経由で定義されるため、参照されたインタフェースは参照の種類がJVMTI_HEAP_REFERENCE_CONSTANT_POOL で報告される可能性もある。
|
JVMTI_HEAP_REFERENCE_STATIC_FIELD | 8 |
クラスからそのいずれかのstaticフィールド値への参照。
|
JVMTI_HEAP_REFERENCE_CONSTANT_POOL | 9 |
クラスから定数プール内の解決済みエントリへの参照。
|
JVMTI_HEAP_REFERENCE_SUPERCLASS | 10 |
クラスからそのスーパー・クラスへの参照。スーパー・クラスがjava.lang.Object の場合、コールバックは送信されない。注: ロードされたクラスは定数プール参照経由でスーパー・クラスを定義するため、参照されたスーパー・クラスは参照の種類がJVMTI_HEAP_REFERENCE_CONSTANT_POOL で報告される可能性もある。
|
JVMTI_HEAP_REFERENCE_JNI_GLOBAL | 21 |
ヒープ・ルート参照: JNIグローバル参照。
|
JVMTI_HEAP_REFERENCE_SYSTEM_CLASS | 22 |
ヒープ・ルート参照: システム・クラス。
|
JVMTI_HEAP_REFERENCE_MONITOR | 23 |
ヒープ・ルート参照: モニター。
|
JVMTI_HEAP_REFERENCE_STACK_LOCAL | 24 |
ヒープ・ルート参照: スタック上の局所変数。
|
JVMTI_HEAP_REFERENCE_JNI_LOCAL | 25 |
ヒープ・ルート参照: JNIローカル参照。
|
JVMTI_HEAP_REFERENCE_THREAD | 26 |
ヒープ・ルート参照: スレッド。
|
JVMTI_HEAP_REFERENCE_OTHER | 27 |
ヒープ・ルート参照: ほかのヒープ・ルート参照。
|
プリミティブ型の単一文字型記述子の定義。
定数
|
値
|
説明
|
JVMTI_PRIMITIVE_TYPE_BOOLEAN | 90 |
「Z」- Javaプログラミング言語のboolean - JNIのjboolean
|
JVMTI_PRIMITIVE_TYPE_BYTE | 66 |
「B」- Javaプログラミング言語のbyte - JNIのjbyte
|
JVMTI_PRIMITIVE_TYPE_CHAR | 67 |
「C」- Javaプログラミング言語のchar - JNIのjchar
|
JVMTI_PRIMITIVE_TYPE_SHORT | 83 |
「S」- Javaプログラミング言語のshort - JNIのjshort
|
JVMTI_PRIMITIVE_TYPE_INT | 73 |
「I」- Javaプログラミング言語のint - JNIのjint
|
JVMTI_PRIMITIVE_TYPE_LONG | 74 |
「J」- Javaプログラミング言語のlong - JNIのjlong
|
JVMTI_PRIMITIVE_TYPE_FLOAT | 70 |
「F」- Javaプログラミング言語のfloat - JNIのjfloat
|
JVMTI_PRIMITIVE_TYPE_DOUBLE | 68 |
「D」- Javaプログラミング言語のdouble - JNIのjdouble
|
フィールド参照用の参照情報構造体
JVMTI_HEAP_REFERENCE_FIELD
およびJVMTI_HEAP_REFERENCE_STATIC_FIELD
参照に対して返される参照情報。
typedef struct {
jint index;
} jvmtiHeapReferenceInfoField;
フィールド
|
型
|
説明
|
index | jint |
JVMTI_HEAP_REFERENCE_FIELD の場合、参照側オブジェクトはクラスでもインタフェースでもありません。この場合、index は、参照側オブジェクトのクラスに含まれるフィールドのインデックスです。以降、このクラスをCと呼びます。
JVMTI_HEAP_REFERENCE_STATIC_FIELD の場合、参照側オブジェクトは、クラス(以降Cと呼ぶ)とインタフェース(以降Iと呼ぶ)のいずれかになります。この場合、index は、そのクラスまたはインタフェースに含まれるフィールドのインデックスです。
参照側オブジェクトがインタフェースでない場合、フィールドのインデックスは次のようにして決定されます。
- Cとそのスーパー・クラスに含まれるすべてのフィールドのリストが作成されます。このリストは、
java.lang.Object 内のすべてのフィールドで始まり、C内のすべてのフィールドで終わります。
- このリスト内で、指定されたクラスのフィールドが
GetClassFields から返された順番に並べられます。
- このリスト内のフィールドに、インデックスn、n+1、... が順に割り当てられます。nは、Cによって実装されたすべてのインタフェースに含まれるフィールドのカウント数です。Cは、そのスーパークラスが直接実装しているすべてのインタフェースと、それらのインタフェースのすべてのスーパーインタフェースを実装しています。
参照側オブジェクトがインタフェースである場合、フィールドのインデックスは次のようにして決定されます。
- I内で直接宣言されているフィールドのリストが作成されます。
- このリスト内のフィールドが
GetClassFields から返された順番に並べられます。
- このリスト内のフィールドに、インデックスn、n+1、... が順に割り当てられます。nは、Iのすべてのスーパー・インタフェースに含まれるフィールドのカウント数です。
この計算には、フィールド修飾子(static、public、privateなど)の種類にかかわらず、すべてのフィールドが含まれます。
たとえば、次のようなクラスとインタフェースが指定されているとします。
interface I0 {
int p = 0;
}
interface I1 extends I0 {
int x = 1;
}
interface I2 extends I0 {
int y = 2;
}
class C1 implements I1 {
public static int a = 3;
private int b = 4;
}
class C2 extends C1 implements I2 {
static int q = 5;
final int r = 6;
}
C1 で呼び出されたGetClassFields から、C1 のフィールドa、bがこの順番で返され、C2 のフィールドq、rがこの順番で返されるものとします。クラスC1 のインスタンスのフィールド・インデックスは、次のようになります。
-
a
|
2
|
C1 が実装するインタフェース内のフィールドのカウント数は2 (n=2)です。つまり、I0 のp とI1 のx です。
|
b
|
3
|
後続のインデックス。
|
クラスC1 も同じフィールド・インデックスを持ちます。
クラスC2 のインスタンスのフィールド・インデックスは、次のようになります。
-
a
|
3
|
C2 が実装するインタフェース内のフィールドのカウント数は3 (n=3)です。つまり、I0 のp 、I1 のx 、I2 のy (C2 のインタフェース)です。I0 のフィールドp が含まれるのは、一度のみです。
|
b
|
4
|
「a」に続くインデックス。
|
q
|
5
|
「b」に続くインデックス。
|
r
|
6
|
「q」に続くインデックス。
|
クラスC2 も同じフィールド・インデックスを持ちます。上記のフィールド「a」のように、同じフィールドが、参照側オブジェクトごとに異なるインデックスを持つ可能性があります。また、コールバックからすべてのフィールド・インデックスが可視になるわけではありませんが、ここでは説明のためにすべてのインデックスを示しています。
インタフェースI1 も同じフィールド・インデックスを持ちます。
-
x
|
1
|
I1 のスーパー・インタフェース内のフィールドのカウント数は1 (n=1)です。つまり、I0 のp です。
|
|
配列参照用の参照情報構造体
JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT
の参照に対して返される参照情報。
typedef struct {
jint index;
} jvmtiHeapReferenceInfoArray;
フィールド
|
型
|
説明
|
index | jint |
配列のインデックス。
|
定数プール参照用の参照情報構造体
JVMTI_HEAP_REFERENCE_CONSTANT_POOL
の参照に対して返される参照情報。
typedef struct {
jint index;
} jvmtiHeapReferenceInfoConstantPool;
フィールド
|
型
|
説明
|
index | jint |
クラスの定数プール内のインデックス。Java(tm)仮想マシン仕様のセクション4.4を参照。
|
局所変数参照用の参照情報構造体
JVMTI_HEAP_REFERENCE_STACK_LOCAL
の参照に対して返される参照情報。
typedef struct {
jlong thread_tag;
jlong thread_id;
jint depth;
jmethodID method;
jlocation location;
jint slot;
} jvmtiHeapReferenceInfoStackLocal;
フィールド
|
型
|
説明
|
thread_tag | jlong |
このスタックに対応するスレッドのタグ。タグ付けされていない場合はゼロ。
|
thread_id | jlong |
このスタックに対応するスレッドの一意のスレッドID。
|
depth | jint |
フレームの深さ。
|
method | jmethodID |
このフレーム内で実行されているメソッド。
|
location | jlocation |
このフレーム内で現在実行されている位置。
|
slot | jint |
局所変数のスロット番号。
|
JNIローカル参照用の参照情報構造体
JVMTI_HEAP_REFERENCE_JNI_LOCAL
の参照に対して返される参照情報。
typedef struct {
jlong thread_tag;
jlong thread_id;
jint depth;
jmethodID method;
} jvmtiHeapReferenceInfoJniLocal;
フィールド
|
型
|
説明
|
thread_tag | jlong |
このスタックに対応するスレッドのタグ。タグ付けされていない場合はゼロ。
|
thread_id | jlong |
このスタックに対応するスレッドの一意のスレッドID。
|
depth | jint |
フレームの深さ。
|
method | jmethodID |
このフレーム内で実行されているメソッド。
|
その他の参照用の参照情報構造体
その他の参照に対して返される参照情報。
typedef struct {
jlong reserved1;
jlong reserved2;
jlong reserved3;
jlong reserved4;
jlong reserved5;
jlong reserved6;
jlong reserved7;
jlong reserved8;
} jvmtiHeapReferenceInfoReserved;
フィールド
|
型
|
説明
|
reserved1 | jlong |
将来の使用のために予約済み。
|
reserved2 | jlong |
将来の使用のために予約済み。
|
reserved3 | jlong |
将来の使用のために予約済み。
|
reserved4 | jlong |
将来の使用のために予約済み。
|
reserved5 | jlong |
将来の使用のために予約済み。
|
reserved6 | jlong |
将来の使用のために予約済み。
|
reserved7 | jlong |
将来の使用のために予約済み。
|
reserved8 | jlong |
将来の使用のために予約済み。
|
参照情報構造体
参照側に関して返される情報。各種参照情報の共用体として表されます。
typedef union {
jvmtiHeapReferenceInfoField field;
jvmtiHeapReferenceInfoArray array;
jvmtiHeapReferenceInfoConstantPool constant_pool;
jvmtiHeapReferenceInfoStackLocal stack_local;
jvmtiHeapReferenceInfoJniLocal jni_local;
jvmtiHeapReferenceInfoReserved other;
} jvmtiHeapReferenceInfo;
ヒープ・コールバック関数構造体
typedef struct {
jvmtiHeapIterationCallback heap_iteration_callback;
jvmtiHeapReferenceCallback heap_reference_callback;
jvmtiPrimitiveFieldCallback primitive_field_callback;
jvmtiArrayPrimitiveValueCallback array_primitive_value_callback;
jvmtiStringPrimitiveValueCallback string_primitive_value_callback;
jvmtiReservedCallback reserved5;
jvmtiReservedCallback reserved6;
jvmtiReservedCallback reserved7;
jvmtiReservedCallback reserved8;
jvmtiReservedCallback reserved9;
jvmtiReservedCallback reserved10;
jvmtiReservedCallback reserved11;
jvmtiReservedCallback reserved12;
jvmtiReservedCallback reserved13;
jvmtiReservedCallback reserved14;
jvmtiReservedCallback reserved15;
} jvmtiHeapCallbacks;
原理の説明: ヒープ・ダンプ機能(下記)では、オブジェクトごとにコールバックが使用されます。バッファ方式の方がスループットが高いように思われますが、テストでは、そのような結果は得られません。メモリー参照の場所または配列アクセスのオーバーヘッドによるものと考えられます。
ヒープ反復コールバック
typedef jint (JNICALL *jvmtiHeapIterationCallback)
(jlong class_tag,
jlong size,
jlong* tag_ptr,
jint length,
void* user_data);
エージェントによって提供されるコールバック関数。ヒープ内のオブジェクトを記述しますが、値は渡しません。
この関数は、必要なビジット制御フラグのビット・ベクトルを返すはずです。これにより、反復処理の全体を中止すべきかどうかが決まります(JVMTI_VISIT_OBJECTS フラグは無視される)。
ヒープ・コールバック関数の制約を参照してください。
名前
|
型
|
説明
|
class_tag | jlong |
オブジェクトのクラスのタグ(タグ付けされていないクラスの場合はゼロ)。オブジェクトが実行時クラスを表す場合、class_tag はjava.lang.Class に関連付けされたタグです(java.lang.Class がタグ付けされていない場合はゼロ)。
|
size | jlong |
オブジェクトのサイズ(バイト単位)。GetObjectSize を参照。
|
tag_ptr | jlong* |
オブジェクトのタグ値(オブジェクトがタグ付けされていない場合はゼロ)。オブジェクトと関連付けるタグの値を設定するため、エージェントはパラメータによってポイントされるjlong を設定する。
|
length | jint |
このオブジェクトが配列である場合はその配列の長さ。それ以外の場合はマイナス1 (-1)。
|
user_data | void* |
ユーザーが入力し、反復関数に渡されたデータ。
|
|
ヒープ参照コールバック
typedef jint (JNICALL *jvmtiHeapReferenceCallback)
(jvmtiHeapReferenceKind reference_kind,
const jvmtiHeapReferenceInfo* reference_info,
jlong class_tag,
jlong referrer_class_tag,
jlong size,
jlong* tag_ptr,
jlong* referrer_tag_ptr,
jint length,
void* user_data);
エージェントによって提供されるコールバック関数。あるオブジェクトまたはVM (参照側)から別のオブジェクト(参照先)への参照、またはあるヒープ・ルートからある参照先への参照を記述します。
この関数は、必要なビジット制御フラグのビット・ベクトルを返すはずです。これにより、参照先が参照しているオブジェクトをビジットすべきかどうかや、反復処理の全体を中止すべきかどうかが決まります。
ヒープ・コールバック関数の制約を参照してください。
|
プリミティブ・フィールド・コールバック
typedef jint (JNICALL *jvmtiPrimitiveFieldCallback)
(jvmtiHeapReferenceKind kind,
const jvmtiHeapReferenceInfo* info,
jlong object_class_tag,
jlong* object_tag_ptr,
jvalue value,
jvmtiPrimitiveType value_type,
void* user_data);
あるオブジェクト(オブジェクト)のプリミティブ・フィールドを記述する、エージェントによって提供されるコールバック関数。プリミティブ・フィールドとは、型がプリミティブ型であるフィールドのことです。このコールバックは、オブジェクトがクラスの場合はstaticフィールドを、それ以外の場合はインスタンス・フィールドをそれぞれ記述します。
この関数は、必要なビジット制御フラグのビット・ベクトルを返すはずです。これにより、反復処理の全体を中止すべきかどうかが決まります(JVMTI_VISIT_OBJECTS フラグは無視される)。
ヒープ・コールバック関数の制約を参照してください。
|
配列プリミティブ値コールバック
typedef jint (JNICALL *jvmtiArrayPrimitiveValueCallback)
(jlong class_tag,
jlong size,
jlong* tag_ptr,
jint element_count,
jvmtiPrimitiveType element_type,
const void* elements,
void* user_data);
エージェントによって提供されるコールバック関数。プリミティブ型の配列内の値を記述します。
この関数は、必要なビジット制御フラグのビット・ベクトルを返すはずです。これにより、反復処理の全体を中止すべきかどうかが決まります(JVMTI_VISIT_OBJECTS フラグは無視される)。
ヒープ・コールバック関数の制約を参照してください。
名前
|
型
|
説明
|
class_tag | jlong |
配列オブジェクトのクラスのタグ(タグ付けされていないクラスの場合はゼロ)。
|
size | jlong |
配列のサイズ(バイト単位)。GetObjectSize を参照。
|
tag_ptr | jlong* |
配列オブジェクトのタグ(オブジェクトがタグ付けされていない場合はゼロ)をポイントする。オブジェクトと関連付けるタグの値を設定するため、エージェントはパラメータによってポイントされるjlong を設定する。
|
element_count | jint |
プリミティブ配列の長さ。
|
element_type | jvmtiPrimitiveType |
配列の要素の型。
|
elements | const void* |
配列の要素。この配列は、element_type のサイズを持つelement_count 個の項目から成るパック配列となる。
|
user_data | void* |
ユーザーが入力し、反復関数に渡されたデータ。
|
|
文字列プリミティブ値コールバック
typedef jint (JNICALL *jvmtiStringPrimitiveValueCallback)
(jlong class_tag,
jlong size,
jlong* tag_ptr,
const jchar* value,
jint value_length,
void* user_data);
エージェントによって提供されるコールバック関数。java.lang.Stringの値を記述します。
この関数は、必要なビジット制御フラグのビット・ベクトルを返すはずです。これにより、反復処理の全体を中止すべきかどうかが決まります(JVMTI_VISIT_OBJECTS フラグは無視される)。
ヒープ・コールバック関数の制約を参照してください。
名前
|
型
|
説明
|
class_tag | jlong |
Stringクラスのクラスのタグ(タグ付けされていないクラスの場合はゼロ)。
|
size | jlong |
文字列のサイズ(バイト単位)。GetObjectSize を参照。
|
tag_ptr | jlong* |
Stringオブジェクトのタグ(オブジェクトがタグ付けされていない場合はゼロ)をポイントする。オブジェクトと関連付けるタグの値を設定するため、エージェントはパラメータによってポイントされるjlong を設定する。
|
value | const jchar* |
Stringの値。Unicode文字列としてエンコードされる。
|
value_length | jint |
文字列の長さ。この長さは、文字列内の16ビットUnicode文字の数に等しくなる。
|
user_data | void* |
ユーザーが入力し、反復関数に渡されたデータ。
|
|
将来使用するために予約されたコールバック
typedef jint (JNICALL *jvmtiReservedCallback)
();
プレースホルダー -- 将来の使用のために予約済み。
|
参照の追跡
jvmtiError
FollowReferences(jvmtiEnv* env,
jint heap_filter,
jclass klass,
jobject initial_object,
const jvmtiHeapCallbacks* callbacks,
const void* user_data)
この関数は、指定されたオブジェクトから直接的、間接的に到達可能なオブジェクト(initial_object
が指定されなかった場合はヒープ・ルートから到達可能なすべてのオブジェクト)に対してトラバーサルを開始します。ヒープ・ルートは、システム・クラス、JNIグローバル、スレッド・スタックからの参照、ガベージ・コレクションの目的でルートとして使用されるその他のオブジェクトのセットです。
この関数は、参照グラフをトラバースすることで動作します。A、B、...がオブジェクトを表すとします。AからBへの参照がトラバースされた場合、ヒープ・ルートからBへの参照がトラバースされた場合、またはBがinitial_object
として指定された場合に、Bがビジットされたと言います。AからBへの参照がトラバースされるのは、Aがビジットされた後です。参照の報告順序は、参照のトラバース順序と同じになります。オブジェクト参照の報告は、エージェントから提供されたコールバック関数jvmtiHeapReferenceCallback
を呼び出すことで行われます。AからBへの参照で、Aは参照元、Bは参照先と呼ばれます。コールバックの呼出しは、参照元からの参照ごとに1回ずつ行われます。これは、参照循環が存在する場合や参照元へのパスが複数存在する場合でも言えることです。参照元と参照先との間に参照が複数存在する可能性もありますが、その場合はそれぞれの参照が報告されます。これらの参照を区別するには、jvmtiHeapReferenceCallback
コールバックのreference_kind
およびreference_info
パラメータを確認します。
この関数が報告するのは、オブジェクト参照のJavaプログラミング言語ビューであり、仮想マシン実装ビューではありません。次のオブジェクト参照が報告されます(nullではない場合)。
- インスタンス・オブジェクトは、各非プリミティブ・インスタンス・フィールド(継承されたフィールドも含む)への参照を報告します。
- インスタンス・オブジェクトは、そのオブジェクトの型(クラス)への参照を報告します。
- クラスは、スーパー・クラスへの参照と、直接実装または拡張したインタフェースへの参照を報告します。
- クラスは、クラス・ローダー、保護ドメイン、署名者、および定数プール内の解決済みエントリへの参照を報告します。
- クラスは、直接宣言された各非プリミティブstaticフィールドへの参照を報告します。
- 配列は、その配列の型(クラス)と各配列要素への参照を報告する。
- プリミティブ配列は、その配列の型への参照を報告します。
またこの関数を使えば、プリミティブ(非オブジェクト)値を確認することもできます。配列またはStringのプリミティブ値が報告されるのは、オブジェクトがビジットされた後です。その報告時には、エージェントが提供するコールバック関数jvmtiArrayPrimitiveValueCallback
またはjvmtiStringPrimitiveValueCallback
が呼び出されます。あるプリミティブ・フィールドが報告されるのは、そのフィールドを含むオブジェクトがビジットされた後です。その報告時には、エージェントが提供するコールバック関数jvmtiPrimitiveFieldCallback
が呼び出されます。
コールバックが提供されるかNULL
であるかは、そのコールバックが呼び出されるかどうかだけを決定し、どのオブジェクトがビジットされるかや、ほかのコールバックが呼び出されるかどうかには影響しません。ただし、jvmtiHeapReferenceCallback
から返されるビジット制御フラグは、現在のオブジェクトが参照しているオブジェクトをビジットするかどうかを決定します。この関数のパラメータとして提供されるヒープ・フィルタ・フラグとklass
は、ビジットされるオブジェクトは制御しませんが、コールバックによって報告されるオブジェクトおよびプリミティブ値は制御します。たとえば、設定された唯一のコールバックがarray_primitive_value_callback
であり、klass
がバイト配列のクラスに設定された場合、バイト配列のみが報告されます。以上をまとめたのが次の表です。
この関数の実行中、ヒープの状態は変化しません。オブジェクトの割当てやガベージ・コレクションは行われず、オブジェクトの状態(保持された値を含む)は変化しません。このため、Javaプログラミング言語コードを実行するスレッド、Javaプログラミング言語コードの実行を再開しようとしているスレッド、およびJNI関数を実行しようとしているスレッドは通常ストールされます。
名前
|
型
|
説明
|
heap_filter | jint |
ヒープ・フィルタ・フラグのこのビット・ベクトルは、コールバック関数の呼出し対象となるオブジェクトを制限します。これはオブジェクト・コールバックとプリミティブ・コールバックの両方に当てはまる。
|
klass | jclass |
コールバックが報告するのは、オブジェクトがこのクラスのインスタンスである場合だけである。klass のスーパー・クラスのインスタンスであるオブジェクトは、報告されません。klass がインタフェースの場合、オブジェクトは報告されません。これはオブジェクト・コールバックとプリミティブ・コールバックの両方に当てはまる。
klass がNULL の場合、コールバックは特定のクラスのインスタンスに制限されません。
|
initial_object | jobject |
追跡するオブジェクト
initial_object がNULL の場合、ヒープ・ルートから参照の追跡が行われる。
|
callbacks | const jvmtiHeapCallbacks * |
一連のコールバック関数を定義する構造体。
エージェントはjvmtiHeapCallbacks へのポインタを渡す。 |
user_data | const void * |
ユーザーが入力し、コールバックに渡されるデータ。
エージェントがポインタを渡す。user_data がNULL の場合、NULL がユーザー指定データとして渡される。
|
ヒープ内での反復
jvmtiError
IterateThroughHeap(jvmtiEnv* env,
jint heap_filter,
jclass klass,
const jvmtiHeapCallbacks* callbacks,
const void* user_data)
ヒープ内のすべてのオブジェクトに対する反復処理を起動します。到達可能なオブジェクトも、そうでないオブジェクトも含まれます。オブジェクトのビジットは特定の順番では行われません。
ヒープ・オブジェクトの報告は、エージェントから提供されるコールバック関数jvmtiHeapIterationCallback
を呼び出すことで行われます。オブジェクト間の参照は報告されません。到達可能なオブジェクトのみが必要である場合や、オブジェクト参照の情報が必要である場合には、FollowReferences
を使用してください。
またこの関数を使えば、プリミティブ(非オブジェクト)値を確認することもできます。配列またはStringのプリミティブ値が報告されるのは、オブジェクトがビジットされた後です。その報告時には、エージェントが提供するコールバック関数jvmtiArrayPrimitiveValueCallback
またはjvmtiStringPrimitiveValueCallback
が呼び出されます。あるプリミティブ・フィールドが報告されるのは、そのフィールドを含むオブジェクトがビジットされた後です。その報告時には、エージェントが提供するコールバック関数jvmtiPrimitiveFieldCallback
が呼び出されます。
コールバックから返されるヒープ・ビジット制御フラグによって反復処理が中止されないかぎり、ヒープ内のすべてのオブジェクトがビジットされます。コールバックが提供されるかNULL
であるかは、そのコールバックが呼び出されるかどうかだけを決定し、どのオブジェクトがビジットされるかや、ほかのコールバックが呼び出されるかどうかには影響しません。この関数のパラメータとして提供されるヒープ・フィルタ・フラグとklass
は、ビジットされるオブジェクトは制御しませんが、コールバックによって報告されるオブジェクトおよびプリミティブ値は制御します。たとえば、設定された唯一のコールバックがarray_primitive_value_callback
であり、klass
がバイト配列のクラスに設定された場合、バイト配列のみが報告されます。これをまとめたのが下の表です(これをFollowReferences
と比較してください)。
この関数の実行中、ヒープの状態は変化しません。オブジェクトの割当てやガベージ・コレクションは行われず、オブジェクトの状態(保持された値を含む)は変化しません。このため、Javaプログラミング言語コードを実行するスレッド、Javaプログラミング言語コードの実行を再開しようとしているスレッド、およびJNI関数を実行しようとしているスレッドは通常ストールされます。
名前
|
型
|
説明
|
heap_filter | jint |
ヒープ・フィルタ・フラグのこのビット・ベクトルは、コールバック関数の呼出し対象となるオブジェクトを制限します。これはオブジェクト・コールバックとプリミティブ・コールバックの両方に当てはまる。
|
klass | jclass |
コールバックが報告するのは、オブジェクトがこのクラスのインスタンスである場合だけである。klass のスーパー・クラスのインスタンスであるオブジェクトは、報告されません。klass がインタフェースの場合、オブジェクトは報告されません。これはオブジェクト・コールバックとプリミティブ・コールバックの両方に当てはまる。
klass がNULL の場合、コールバックは特定のクラスのインスタンスに制限されません。
|
callbacks | const jvmtiHeapCallbacks * |
一連のコールバック関数を定義する構造体。
エージェントはjvmtiHeapCallbacks へのポインタを渡す。 |
user_data | const void * |
ユーザーが入力し、コールバックに渡されるデータ。
エージェントがポインタを渡す。user_data がNULL の場合、NULL がユーザー指定データとして渡される。
|
タグの取得
jvmtiError
GetTag(jvmtiEnv* env,
jobject object,
jlong* tag_ptr)
オブジェクトに関連付けられているタグを取得します。タグは長整数値で、通常、オブジェクト情報の一意の識別子またはポインタを格納するために使用されます。タグの設定には、SetTag
関数を使用します。タグが設定されていないオブジェクトは、タグ値としてゼロを返します。
名前
|
型
|
説明
|
object | jobject |
タグが取得されるオブジェクト。
|
tag_ptr | jlong* |
戻ったとき、参照される長整数値にタグ値が設定されている。
エージェントはjlong へのポインタを渡す。戻ったとき、jlong が設定されている。 |
タグの設定
jvmtiError
SetTag(jvmtiEnv* env,
jobject object,
jlong tag)
オブジェクトに関連付けられているタグを設定します。タグは長整数値で、通常、オブジェクト情報の一意の識別子またはポインタを格納するために使用されます。タグの表示には、GetTag
関数を使用します。
タグを使ったオブジェクトの取得
jvmtiError
GetObjectsWithTags(jvmtiEnv* env,
jint tag_count,
const jlong* tags,
jint* count_ptr,
jobject** object_result_ptr,
jlong** tag_result_ptr)
ヒープ内の指定されたタグを持つオブジェクトを返します。オブジェクトとタグの並行配列の形式になります。
名前
|
型
|
説明
|
tag_count | jint |
走査するタグの数。
|
tags | const jlong * |
これらのタグが付けられたオブジェクトを走査する。この配列内では、ゼロは使用できない。
エージェントはjlong のtag_count 要素の配列を渡す。 |
count_ptr | jint * |
tags 内の任意のタグを持つオブジェクトの数を返す。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
object_result_ptr | jobject ** |
tags 内の任意のタグを持つオブジェクトの配列を返す。
エージェントはjobject* へのポインタを渡す。戻ったとき、jobject* は、サイズ*count_ptr の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。object_result_ptr がNULL の場合、この情報は返されない。object_result_ptr から返されるオブジェクトはJNIローカル参照であり、管理する必要がある。
|
tag_result_ptr | jlong ** |
object_result_ptr 内の各オブジェクトに対して、対応するインデックスのタグを返す。
エージェントはjlong* へのポインタを渡す。戻ったとき、jlong* は、サイズ*count_ptr の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。tag_result_ptr がNULL の場合、この情報は返されない。
|
ガベージ・コレクションの強制
jvmtiError
ForceGarbageCollection(jvmtiEnv* env)
VMにガベージ・コレクションの実行を強制します。ガベージ・コレクションは可能なかぎり完全に行われます。この関数は、ファイナライザを実行させません。この関数は、ガベージ・コレクションが完了するまで終了しません。
ガベージ・コレクションは可能なかぎり完全に実行されますが、この関数が戻るまでにすべてのObjectFree
イベントが送信されているという保証はありません。特に、ファイナライズ待ちのオブジェクトが解放されない可能性があります。
ヒープ(1.0)
ヒープ(1.0)の関数:
ヒープ(1.0)の関数型:
ヒープ(1.0)の型:
これらの関数およびデータ型は元のJVM TI Version 1.0で導入されたものであり、より強力で柔軟性の高いバージョンで置き換えられました。新しいバージョンの特徴を次に示します。
-
プリミティブ値(Strings、配列、およびプリミティブ・フィールドの値)へのアクセスを可能にする
-
参照側のタグを設定できるようにする。このため、より効率的なローカライズされた参照グラフの構築が可能となる
-
より広範なフィルタ・リング機能を提供する
-
拡張可能である。このため、JVM TIの将来のバージョンで拡張を施すことができる
現在のヒープ関数を使用してください。
定数
|
値
|
説明
|
JVMTI_HEAP_OBJECT_TAGGED | 1 |
タグ付きオブジェクトのみ。
|
JVMTI_HEAP_OBJECT_UNTAGGED | 2 |
タグなしオブジェクトのみ。
|
JVMTI_HEAP_OBJECT_EITHER | 3 |
タグ付きオブジェクトまたはタグなしオブジェクト。
|
定数
|
値
|
説明
|
JVMTI_HEAP_ROOT_JNI_GLOBAL | 1 |
JNIグローバル参照。
|
JVMTI_HEAP_ROOT_SYSTEM_CLASS | 2 |
システム・クラス。
|
JVMTI_HEAP_ROOT_MONITOR | 3 |
モニター。
|
JVMTI_HEAP_ROOT_STACK_LOCAL | 4 |
スタック・ローカル。
|
JVMTI_HEAP_ROOT_JNI_LOCAL | 5 |
JNIローカル参照。
|
JVMTI_HEAP_ROOT_THREAD | 6 |
スレッド。
|
JVMTI_HEAP_ROOT_OTHER | 7 |
その他。
|
定数
|
値
|
説明
|
JVMTI_REFERENCE_CLASS | 1 |
オブジェクトからそのクラスへの参照。
|
JVMTI_REFERENCE_FIELD | 2 |
オブジェクトから、そのオブジェクトのいずれかのインスタンス・フィールド値への参照。この種の参照の場合、jvmtiObjectReferenceCallbackのreferrer_index パラメータはインスタンス・フィールドのインデックス。インデックスは、すべてのオブジェクトのフィールドの順序が基になる。クラスで直接宣言されたstaticおよびインスタンス・フィールドが含まれるほか、スーパー・クラスおよびスーパー・インタフェースで宣言されたすべてのフィールド(publicとprivateの両方)が含まれる。そのためインデックスは、直接宣言されたクラスにあるフィールドのインデックス(GetClassFields 参照)と、すべてのスーパー・クラスおよびスーパー・インタフェースで宣言されたフィールド(publicとprivateの両方)の合計数を足し合わせたもので計算されます。インデックスは0から始まる。
|
JVMTI_REFERENCE_ARRAY_ELEMENT | 3 |
配列から、その配列のいずれかの要素への参照。この種の参照の場合、jvmtiObjectReferenceCallbackのreferrer_index パラメータは配列のインデックス。
|
JVMTI_REFERENCE_CLASS_LOADER | 4 |
クラスからそのクラス・ローダーへの参照。
|
JVMTI_REFERENCE_SIGNERS | 5 |
クラスからその署名者の配列への参照。
|
JVMTI_REFERENCE_PROTECTION_DOMAIN | 6 |
クラスからその保護ドメインへの参照。
|
JVMTI_REFERENCE_INTERFACE | 7 |
クラスから、そのクラスのいずれかのインタフェースへの参照。
|
JVMTI_REFERENCE_STATIC_FIELD | 8 |
クラスからそのいずれかのstaticフィールド値への参照。この種の参照の場合、jvmtiObjectReferenceCallbackのreferrer_index パラメータはstaticフィールドのインデックス。インデックスは、すべてのオブジェクトのフィールドの順序が基になる。クラスで直接宣言されたstaticおよびインスタンス・フィールドが含まれるほか、スーパー・クラスおよびスーパー・インタフェースで宣言されたすべてのフィールド(publicとprivateの両方)が含まれる。そのためインデックスは、直接宣言されたクラスにあるフィールドのインデックス(GetClassFields 参照)と、すべてのスーパー・クラスおよびスーパー・インタフェースで宣言されたフィールド(publicとprivateの両方)の合計数を足し合わせたもので計算されます。インデックスは0から始まる。注: この定義は、JVM TI 1.0仕様での定義と異なる。
原理の説明: 既知の実装のなかで、1.0の定義を使用したものはない。
|
JVMTI_REFERENCE_CONSTANT_POOL | 9 |
クラスから定数プール内の解決済みエントリへの参照。この種の参照の場合、jvmtiObjectReferenceCallbackのreferrer_index パラメータは、クラスの定数プール・テーブルのインデックスで、1から始まる。Java(tm)仮想マシン仕様のセクション4.4を参照。
|
定数
|
値
|
説明
|
JVMTI_ITERATION_CONTINUE | 1 |
反復処理を継続。参照の反復処理の場合、このオブジェクトの参照に従う。
|
JVMTI_ITERATION_IGNORE | 2 |
反復処理を継続。参照の反復処理の場合、このオブジェクトの参照を無視する。
|
JVMTI_ITERATION_ABORT | 0 |
反復処理を中止。
|
ヒープ・オブジェクトのコールバック
typedef jvmtiIterationControl (JNICALL *jvmtiHeapObjectCallback)
(jlong class_tag,
jlong size,
jlong* tag_ptr,
void* user_data);
エージェントによって提供されるコールバック関数。ヒープ内のオブジェクトを記述しますが、値は渡しません。
反復処理を継続する場合、戻り値はJVMTI_ITERATION_CONTINUE です。反復処理を停止する場合、戻り値はJVMTI_ITERATION_ABORT です。
ヒープ・コールバック関数の制約を参照してください。
名前
|
型
|
説明
|
class_tag | jlong |
オブジェクトのクラスのタグ(タグ付けされていないクラスの場合はゼロ)。オブジェクトが実行時クラスを表す場合、class_tag はjava.lang.Class に関連付けされたタグです(java.lang.Class がタグ付けされていない場合はゼロ)。
|
size | jlong |
オブジェクトのサイズ(バイト単位)。GetObjectSize を参照。
|
tag_ptr | jlong* |
オブジェクトのタグ値(オブジェクトがタグ付けされていない場合はゼロ)。オブジェクトと関連付けるタグの値を設定するため、エージェントはパラメータによってポイントされるjlong を設定する。
|
user_data | void* |
ユーザーが入力し、反復関数に渡されたデータ。
|
|
ヒープ・ルート・オブジェクトのコールバック
typedef jvmtiIterationControl (JNICALL *jvmtiHeapRootCallback)
(jvmtiHeapRootKind root_kind,
jlong class_tag,
jlong size,
jlong* tag_ptr,
void* user_data);
エージェントによって提供されるコールバック関数。ガベージ・コレクションの目的で、ルート・オブジェクトについて説明しますが、値は渡しません。
戻り値は、反復処理を継続する場合はJVMTI_ITERATION_CONTINUE 、参照側オブジェクトからの参照を続行しないで反復処理を継続する場合はJVMTI_ITERATION_IGNORE 、反復処理を停止する場合はJVMTI_ITERATION_ABORT のはずです。
ヒープ・コールバック関数の制約を参照してください。
名前
|
型
|
説明
|
root_kind | jvmtiHeapRootKind |
ヒープ・ルートの種類。
|
class_tag | jlong |
オブジェクトのクラスのタグ(タグ付けされていないクラスの場合はゼロ)。オブジェクトが実行時クラスを表す場合、class_tag はjava.lang.Class に関連付けされたタグです(java.lang.Class がタグ付けされていない場合はゼロ)。
|
size | jlong |
オブジェクトのサイズ(バイト単位)。GetObjectSize を参照。
|
tag_ptr | jlong* |
オブジェクトのタグ値(オブジェクトがタグ付けされていない場合はゼロ)。オブジェクトと関連付けるタグの値を設定するため、エージェントはパラメータによってポイントされるjlong を設定する。
|
user_data | void* |
ユーザーが入力し、反復関数に渡されたデータ。
|
|
スタック参照オブジェクトのコールバック
typedef jvmtiIterationControl (JNICALL *jvmtiStackReferenceCallback)
(jvmtiHeapRootKind root_kind,
jlong class_tag,
jlong size,
jlong* tag_ptr,
jlong thread_tag,
jint depth,
jmethodID method,
jint slot,
void* user_data);
エージェントによって提供されるコールバック関数。ガベージ・コレクションの目的で、スタック上のルート・オブジェクトについて説明しますが、値は渡しません。
戻り値は、反復処理を継続する場合はJVMTI_ITERATION_CONTINUE 、参照側オブジェクトからの参照を続行しないで反復処理を継続する場合はJVMTI_ITERATION_IGNORE 、反復処理を停止する場合はJVMTI_ITERATION_ABORT のはずです。
ヒープ・コールバック関数の制約を参照してください。
名前
|
型
|
説明
|
root_kind | jvmtiHeapRootKind |
ルートの種類(JVMTI_HEAP_ROOT_STACK_LOCAL またはJVMTI_HEAP_ROOT_JNI_LOCAL )。
|
class_tag | jlong |
オブジェクトのクラスのタグ(タグ付けされていないクラスの場合はゼロ)。オブジェクトが実行時クラスを表す場合、class_tag はjava.lang.Class に関連付けされたタグです(java.lang.Class がタグ付けされていない場合はゼロ)。
|
size | jlong |
オブジェクトのサイズ(バイト単位)。GetObjectSize を参照。
|
tag_ptr | jlong* |
オブジェクトのタグ値(オブジェクトがタグ付けされていない場合はゼロ)。オブジェクトと関連付けるタグの値を設定するため、エージェントはパラメータによってポイントされるjlong を設定する。
|
thread_tag | jlong |
このスタックに対応するスレッドのタグ。タグ付けされていない場合はゼロ。
|
depth | jint |
フレームの深さ。
|
method | jmethodID |
このフレーム内で実行されているメソッド。
|
slot | jint |
スロット番号。
|
user_data | void* |
ユーザーが入力し、反復関数に渡されたデータ。
|
|
オブジェクト参照のコールバック
typedef jvmtiIterationControl (JNICALL *jvmtiObjectReferenceCallback)
(jvmtiObjectReferenceKind reference_kind,
jlong class_tag,
jlong size,
jlong* tag_ptr,
jlong referrer_tag,
jint referrer_index,
void* user_data);
エージェントによって提供されるコールバック関数。あるオブジェクト(参照側)から別のオブジェクト(参照先)の参照について説明します。
戻り値は、反復処理を継続する場合はJVMTI_ITERATION_CONTINUE 、参照側オブジェクトからの参照を続行しないで反復処理を継続する場合はJVMTI_ITERATION_IGNORE 、反復処理を停止する場合はJVMTI_ITERATION_ABORT のはずです。
ヒープ・コールバック関数の制約を参照してください。
名前
|
型
|
説明
|
reference_kind | jvmtiObjectReferenceKind |
参照型。
|
class_tag | jlong |
参照されるオブジェクトのクラスのタグ(タグ付けされていないクラスの場合はゼロ)。参照先オブジェクトが実行時クラスを表す場合、class_tag はjava.lang.Class に関連付けされたタグです(java.lang.Class がタグ付けされていない場合はゼロ)。
|
size | jlong |
参照されるオブジェクトのサイズ(バイト単位)。GetObjectSize を参照。
|
tag_ptr | jlong* |
参照オブジェクトのタグ値(オブジェクトがタグ付けされていない場合はゼロ)。オブジェクトと関連付けるタグの値を設定するため、エージェントはパラメータによってポイントされるjlong を設定する。
|
referrer_tag | jlong |
参照側のオブジェクトのタグ値。タグ付けされていないオブジェクトの場合はゼロ。
|
referrer_index | jint |
JVMTI_REFERENCE_FIELD またはJVMTI_REFERENCE_STATIC_FIELD 型の参照の場合、参照元オブジェクト内のフィールドのインデックス。このインデックスは、オブジェクトのすべてのフィールドの順番に基づく。詳しい説明については、JVMTI_REFERENCE_FIELDまたはJVMTI_REFERENCE_STATIC_FIELD を参照。
型JVMTI_REFERENCE_ARRAY_ELEMENT の参照の場合は、配列インデックス。詳細な説明については、JVMTI_REFERENCE_ARRAY_ELEMENTを参照。
型JVMTI_REFERENCE_CONSTANT_POOL の参照の場合は、クラスの定数プールに対するインデックス。詳細な説明については、JVMTI_REFERENCE_CONSTANT_POOLを参照。
その他の参照の場合、referrer_index は-1 。
|
user_data | void* |
ユーザーが入力し、反復関数に渡されたデータ。
|
|
オブジェクトから到達可能なオブジェクトの反復
jvmtiError
IterateOverObjectsReachableFromObject(jvmtiEnv* env,
jobject object,
jvmtiObjectReferenceCallback object_reference_callback,
const void* user_data)
この関数は、指定されたオブジェクトから直接的または間接的に到達可能なすべてのオブジェクトに対して反復処理を行います。オブジェクトBを参照する各オブジェクトA(参照元と呼ばれる)に対し、そのオブジェクト参照を記述する目的で、指定されたコールバック関数が呼び出されます。コールバックの呼出しは、参照元からの参照ごとに1回ずつ行われます。これは、参照循環が存在する場合や参照元へのパスが複数存在する場合でも言えることです。参照元と参照先との間の参照は複数存在する可能性があります。これらを区別するには、jvmtiObjectReferenceCallback.reference_kind
およびjvmtiObjectReferenceCallback.referrer_index
を使用します。あるオブジェクトのコールバックは必ず、その参照元のコールバックの後で発生します。
報告されるオブジェクト参照については、FollowReferences
を参照してください。
この関数の実行中、ヒープの状態は変化しません。オブジェクトの割当てやガベージ・コレクションは行われず、オブジェクトの状態(保持された値を含む)は変化しません。このため、Javaプログラミング言語コードを実行するスレッド、Javaプログラミング言語コードの実行を再開しようとしているスレッド、およびJNI関数を実行しようとしているスレッドは通常ストールされます。
名前
|
型
|
説明
|
object | jobject |
オブジェクト
|
object_reference_callback | jvmtiObjectReferenceCallback |
各オブジェクト参照を記述するために呼び出されるコールバック。
|
user_data | const void * |
ユーザーが入力し、コールバックに渡されるデータ。
エージェントがポインタを渡す。user_data がNULL の場合、NULL がユーザー指定データとして渡される。
|
到達可能なオブジェクトの反復
jvmtiError
IterateOverReachableObjects(jvmtiEnv* env,
jvmtiHeapRootCallback heap_root_callback,
jvmtiStackReferenceCallback stack_ref_callback,
jvmtiObjectReferenceCallback object_ref_callback,
const void* user_data)
この関数は、ルート・オブジェクトと、ルート・オブジェクトから直接または間接的に到達可能なすべてのオブジェクトに対して反復処理を行います。ルート・オブジェクトは、システム・クラス、JNIグローバル、スレッド・スタックからの参照、ガベージ・コレクションの目的でルートとして使用されるその他のオブジェクトのセットで構成されます。
各ルートに対して、heap_root_callback
またはstack_ref_callback
コールバックが呼び出されます。オブジェクトは複数の理由でルート・オブジェクトになる可能性がありますが、その場合、対応するコールバックが理由ごとに呼び出されます。
各オブジェクト参照について、そのオブジェクト参照を記述する目的でobject_ref_callback
コールバック関数が呼び出されます。コールバックの呼出しは、参照元からの参照ごとに1回ずつ行われます。これは、参照循環が存在する場合や参照元へのパスが複数存在する場合でも言えることです。参照元と参照先との間の参照は複数存在する可能性があります。これらを区別するには、jvmtiObjectReferenceCallback.reference_kind
およびjvmtiObjectReferenceCallback.referrer_index
を使用します。あるオブジェクトのコールバックは必ず、その参照元のコールバックの後で発生します。
報告されるオブジェクト参照については、FollowReferences
を参照してください。
ルートは、常に、オブジェクト参照が報告される前に、プロファイラに報告されます。つまり、object_ref_callback
は、すべてのルートに対して適切なコールバックが呼び出されるまで、呼び出されません。object_ref_callback
がNULL
と指定されている場合、この関数は、プロファイラにルート・オブジェクトを報告したあと、終了します。
この関数の実行中、ヒープの状態は変化しません。オブジェクトの割当てやガベージ・コレクションは行われず、オブジェクトの状態(保持された値を含む)は変化しません。このため、Javaプログラミング言語コードを実行するスレッド、Javaプログラミング言語コードの実行を再開しようとしているスレッド、およびJNI関数を実行しようとしているスレッドは通常ストールされます。
名前
|
型
|
説明
|
heap_root_callback | jvmtiHeapRootCallback |
JVMTI_HEAP_ROOT_JNI_GLOBAL 、JVMTI_HEAP_ROOT_SYSTEM_CLASS 、JVMTI_HEAP_ROOT_MONITOR 、JVMTI_HEAP_ROOT_THREAD 、またはJVMTI_HEAP_ROOT_OTHER 型の各ヒープ・ルートのために呼び出されるコールバック関数。
heap_root_callback がNULL の場合、ヒープ・ルートの報告は行わない。
|
stack_ref_callback | jvmtiStackReferenceCallback |
JVMTI_HEAP_ROOT_STACK_LOCAL またはJVMTI_HEAP_ROOT_JNI_LOCAL の各ヒープ・ルートのために呼び出されるコールバック関数。
stack_ref_callback がNULL の場合、スタック参照の報告は行わない。
|
object_ref_callback | jvmtiObjectReferenceCallback |
各オブジェクト参照のために呼び出されるコールバック関数。
object_ref_callback がNULL の場合、ルート・オブジェクトからの参照には従わない。
|
user_data | const void * |
ユーザーが入力し、コールバックに渡されるデータ。
エージェントがポインタを渡す。user_data がNULL の場合、NULL がユーザー指定データとして渡される。
|
ヒープの反復
jvmtiError
IterateOverHeap(jvmtiEnv* env,
jvmtiHeapObjectFilter object_filter,
jvmtiHeapObjectCallback heap_object_callback,
const void* user_data)
ヒープ内のすべてのオブジェクトに対して反復処理を行います。到達可能なオブジェクトも、そうでないオブジェクトも含まれます。
object_filter
パラメータは、どのオブジェクトのためにコールバック関数が呼び出されるかを示します。パラメータがJVMTI_HEAP_OBJECT_TAGGED
の場合、コールバックは、すべてのタグ付きオブジェクトに対してのみ呼び出されます。パラメータがJVMTI_HEAP_OBJECT_UNTAGGED
の場合、コールバックは、すべてのタグなしオブジェクトに対してのみ呼び出されます。パラメータがJVMTI_HEAP_OBJECT_EITHER
の場合、コールバックは、タグが付いているかどうかに関係なく、ヒープ内のすべてのオブジェクトに対して呼び出されます。
この関数の実行中、ヒープの状態は変化しません。オブジェクトの割当てやガベージ・コレクションは行われず、オブジェクトの状態(保持された値を含む)は変化しません。このため、Javaプログラミング言語コードを実行するスレッド、Javaプログラミング言語コードの実行を再開しようとしているスレッド、およびJNI関数を実行しようとしているスレッドは通常ストールされます。
クラスのインスタンスの反復
jvmtiError
IterateOverInstancesOfClass(jvmtiEnv* env,
jclass klass,
jvmtiHeapObjectFilter object_filter,
jvmtiHeapObjectCallback heap_object_callback,
const void* user_data)
指定されたクラスのインスタンスになっている、ヒープ内のすべてのオブジェクトに対して反復処理を行います。これには、指定されたクラスの直接のインスタンスと、指定されたクラスのすべてのサブクラスのインスタンスが含まれます。到達可能なオブジェクトも、そうでないオブジェクトも含まれます。
object_filter
パラメータは、どのオブジェクトのためにコールバック関数が呼び出されるかを示します。パラメータがJVMTI_HEAP_OBJECT_TAGGED
の場合、コールバックは、すべてのタグ付きオブジェクトに対してのみ呼び出されます。パラメータがJVMTI_HEAP_OBJECT_UNTAGGED
の場合、コールバックは、すべてのタグなしオブジェクトに対してのみ呼び出されます。パラメータがJVMTI_HEAP_OBJECT_EITHER
の場合、コールバックは、タグが付いているかどうかに関係なく、ヒープ内のすべてのオブジェクトに対して呼び出されます。
この関数の実行中、ヒープの状態は変化しません。オブジェクトの割当てやガベージ・コレクションは行われず、オブジェクトの状態(保持された値を含む)は変化しません。このため、Javaプログラミング言語コードを実行するスレッド、Javaプログラミング言語コードの実行を再開しようとしているスレッド、およびJNI関数を実行しようとしているスレッドは通常ストールされます。
局所変数
局所変数関数:
これらの関数は、局所変数の値を取得または設定するために使います。変数は、変数の値を含んでいるフレームの深さと、そのフレーム内の変数のスロット番号によって識別されます。変数からスロット番号へのマッピングは、関数GetLocalVariableTable
を使って取得できます。
局所変数の取得 - オブジェクト型
jvmtiError
GetLocalObject(jvmtiEnv* env,
jthread thread,
jint depth,
jint slot,
jobject* value_ptr)
この関数を使うと、型がObject
またはObject
のサブクラスである局所変数の値を取得できます。
名前
|
型
|
説明
|
thread | jthread |
変数の値を含むフレームのスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
depth | jint |
変数の値を含むフレームの深さ。
|
slot | jint |
変数のスロット番号。
|
value_ptr | jobject* |
戻ったとき、変数の値をポイントする。
エージェントはjobject へのポインタを渡す。戻ったとき、jobject が設定されている。value_ptr から返されるオブジェクトはJNIローカル参照であり、管理する必要がある。
|
局所インスタンスの取得
jvmtiError
GetLocalInstance(jvmtiEnv* env,
jthread thread,
jint depth,
jobject* value_ptr)
この関数を使うと、静的でないフレームからスロット0 (「this
」オブジェクト)の局所オブジェクト変数の値を取得できます。この関数は、ネイティブ・メソッドのフレームから「this
」オブジェクトを取得しますが、この場合、GetLocalObject()
はJVMTI_ERROR_OPAQUE_FRAME
を返します。
名前
|
型
|
説明
|
thread | jthread |
変数の値を含むフレームのスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
depth | jint |
変数の値を含むフレームの深さ。
|
value_ptr | jobject* |
戻ったとき、変数の値をポイントする。
エージェントはjobject へのポインタを渡す。戻ったとき、jobject が設定されている。value_ptr から返されるオブジェクトはJNIローカル参照であり、管理する必要がある。
|
局所変数の取得 - 整数型
jvmtiError
GetLocalInt(jvmtiEnv* env,
jthread thread,
jint depth,
jint slot,
jint* value_ptr)
この関数を使うと、型がint
、short
、char
、byte
、boolean
のいずれかである局所変数の値を取得できます。
名前
|
型
|
説明
|
thread | jthread |
変数の値を含むフレームのスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
depth | jint |
変数の値を含むフレームの深さ。
|
slot | jint |
変数のスロット番号。
|
value_ptr | jint* |
戻ったとき、変数の値をポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
局所変数の取得 - 長整数型
jvmtiError
GetLocalLong(jvmtiEnv* env,
jthread thread,
jint depth,
jint slot,
jlong* value_ptr)
この関数を使うと、型がlong
である局所変数の値を取得できます。
名前
|
型
|
説明
|
thread | jthread |
変数の値を含むフレームのスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
depth | jint |
変数の値を含むフレームの深さ。
|
slot | jint |
変数のスロット番号。
|
value_ptr | jlong* |
戻ったとき、変数の値をポイントする。
エージェントはjlong へのポインタを渡す。戻ったとき、jlong が設定されている。 |
局所変数の取得 - 浮動小数点数型
jvmtiError
GetLocalFloat(jvmtiEnv* env,
jthread thread,
jint depth,
jint slot,
jfloat* value_ptr)
この関数を使うと、型がfloat
である局所変数の値を取得できます。
名前
|
型
|
説明
|
thread | jthread |
変数の値を含むフレームのスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
depth | jint |
変数の値を含むフレームの深さ。
|
slot | jint |
変数のスロット番号。
|
value_ptr | jfloat* |
戻ったとき、変数の値をポイントする。
エージェントはjfloat へのポインタを渡す。戻ったとき、jfloat が設定されている。 |
局所変数の取得 - 倍精度浮動小数点数型
jvmtiError
GetLocalDouble(jvmtiEnv* env,
jthread thread,
jint depth,
jint slot,
jdouble* value_ptr)
この関数を使うと、型がlong
である局所変数の値を取得できます。
名前
|
型
|
説明
|
thread | jthread |
変数の値を含むフレームのスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
depth | jint |
変数の値を含むフレームの深さ。
|
slot | jint |
変数のスロット番号。
|
value_ptr | jdouble* |
戻ったとき、変数の値をポイントする。
エージェントはjdouble へのポインタを渡す。戻ったとき、jdouble が設定されている。 |
局所変数の設定 - オブジェクト型
jvmtiError
SetLocalObject(jvmtiEnv* env,
jthread thread,
jint depth,
jint slot,
jobject value)
この関数を使うと、型がObject
またはObject
のサブクラスである局所変数の値を設定できます。
名前
|
型
|
説明
|
thread | jthread |
変数の値を含むフレームのスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
depth | jint |
変数の値を含むフレームの深さ。
|
slot | jint |
変数のスロット番号。
|
value | jobject |
変数の新しい値。
|
局所変数の設定 - 整数型
jvmtiError
SetLocalInt(jvmtiEnv* env,
jthread thread,
jint depth,
jint slot,
jint value)
この関数を使うと、型がint
、short
、char
、byte
、boolean
のいずれかである局所変数の値を設定できます。
名前
|
型
|
説明
|
thread | jthread |
変数の値を含むフレームのスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
depth | jint |
変数の値を含むフレームの深さ。
|
slot | jint |
変数のスロット番号。
|
value | jint |
変数の新しい値。
|
局所変数の設定 - 長整数型
jvmtiError
SetLocalLong(jvmtiEnv* env,
jthread thread,
jint depth,
jint slot,
jlong value)
この関数を使うと、型がlong
である局所変数の値を設定できます。
名前
|
型
|
説明
|
thread | jthread |
変数の値を含むフレームのスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
depth | jint |
変数の値を含むフレームの深さ。
|
slot | jint |
変数のスロット番号。
|
value | jlong |
変数の新しい値。
|
局所変数の設定 - 浮動小数点数型
jvmtiError
SetLocalFloat(jvmtiEnv* env,
jthread thread,
jint depth,
jint slot,
jfloat value)
この関数を使うと、型がfloat
である局所変数の値を設定できます。
名前
|
型
|
説明
|
thread | jthread |
変数の値を含むフレームのスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
depth | jint |
変数の値を含むフレームの深さ。
|
slot | jint |
変数のスロット番号。
|
value | jfloat |
変数の新しい値。
|
局所変数の設定 - 倍精度浮動小数点数型
jvmtiError
SetLocalDouble(jvmtiEnv* env,
jthread thread,
jint depth,
jint slot,
jdouble value)
この関数を使うと、型がdouble
である局所変数の値を設定できます。
名前
|
型
|
説明
|
thread | jthread |
変数の値を含むフレームのスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
depth | jint |
変数の値を含むフレームの深さ。
|
slot | jint |
変数のスロット番号。
|
value | jdouble |
変数の新しい値。
|
ブレークポイント
ブレークポイント関数:
ブレークポイントの設定
jvmtiError
SetBreakpoint(jvmtiEnv* env,
jmethodID method,
jlocation location)
method
およびlocation
で指定された命令にブレークポイントを設定します。1つの命令に対して設定できるブレークポイントは1つだけです。
指定した命令が実行される直前に、Breakpoint
イベントが生成されます。
ブレークポイントの解除
jvmtiError
ClearBreakpoint(jvmtiEnv* env,
jmethodID method,
jlocation location)
method
およびlocation
で指定されたバイト・コードに設定されているブレークポイントを解除します。
監視されるフィールド
監視されるフィールド関数:
フィールド・アクセスの監視の設定
jvmtiError
SetFieldAccessWatch(jvmtiEnv* env,
jclass klass,
jfieldID field)
klass
およびfield
で指定されたフィールドがアクセスされようとした時点で、FieldAccess
イベントを生成します。イベントは、ClearFieldAccessWatch
を使用して取り消されるまで、フィールドがアクセスされるたびに生成されます。Javaプログラミング言語コードまたはJNIコードからのフィールド・アクセスが監視され、他の手段で変更されるフィールドは監視されません。JVM TIのユーザーは、自分自身のフィールド・アクセスによって監視イベントがトリガーされることに注意してください。1つのフィールドに対し、フィールド・アクセスの監視を1つのみ設定できます。フィールドの変更はアクセスとはみなされません。変更を監視するにはSetFieldModificationWatch
を使用します。
フィールド・アクセスの監視の解除
jvmtiError
ClearFieldAccessWatch(jvmtiEnv* env,
jclass klass,
jfieldID field)
SetFieldAccessWatch
を使って以前に設定した、klass
およびfield
で指定されるフィールドに対するフィールド・アクセスの監視を取り消します。
フィールド変更の監視の設定
jvmtiError
SetFieldModificationWatch(jvmtiEnv* env,
jclass klass,
jfieldID field)
klass
およびfield
で指定されたフィールドが変更されようとした時点で、FieldModification
イベントを生成します。イベントは、ClearFieldModificationWatch
を使って取り消されるまで、フィールドが変更されるたびに生成されます。Javaプログラミング言語コードまたはJNIコードからのフィールド変更が監視され、ほかの手段で変更されるフィールドは監視されません。JVM TIのユーザーは、自分自身のフィールド変更によって監視イベントがトリガーされることに注意してください。1つのフィールドに対し、フィールド変更の監視を1つだけ設定できます。
フィールド変更の監視の解除
jvmtiError
ClearFieldModificationWatch(jvmtiEnv* env,
jclass klass,
jfieldID field)
klass
およびfield
で指定されるフィールドに対して、SetFieldModificationWatch
を使って以前に設定したフィールド変更の監視を取り消します。
クラス
クラス関数:
クラスの型:
クラスのフラグおよび定数:
ロード済みクラスの取得
jvmtiError
GetLoadedClasses(jvmtiEnv* env,
jint* class_count_ptr,
jclass** classes_ptr)
仮想マシンにロードされている全クラスの配列を返します。配列内のクラスの数はclass_count_ptr
、配列自体はclasses_ptr
によって返されます。
返されるリストには、すべての型の配列クラス(プリミティブ型の配列を含む)が含まれます。プリミティブ・クラス(たとえば、java.lang.Integer.TYPE
)は、このリストには含まれません。
名前
|
型
|
説明
|
class_count_ptr | jint* |
戻ったとき、クラスの数をポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
classes_ptr | jclass** |
戻ったとき、各クラスへの参照(クラスごとに1つずつ)の配列をポイントする。
エージェントはjclass* へのポインタを渡す。戻ったとき、jclass* は、サイズ*class_count_ptr の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。classes_ptr から返されるオブジェクトはJNIローカル参照であり、管理する必要がある。
|
クラス・ローダー・クラスの取得
jvmtiError
GetClassLoaderClasses(jvmtiEnv* env,
jobject initiating_loader,
jint* class_count_ptr,
jclass** classes_ptr)
このクラス・ローダーが起動ローダーとして記録されているクラスの配列を返します。返される配列内の各クラスは、このクラス・ローダーによって直接定義されて作成されたものか、または別のクラス・ローダーに委譲して作成されたものです。Java(tm)仮想マシン仕様のセクション5.3を参照してください。
JDK 1.1の実装では、起動クラス・ローダーと定義クラス・ローダーの区別が認識されないため、この関数は、仮想マシンにロードされたすべてのクラスを返します。配列内のクラスの数はclass_count_ptr
、配列自体はclasses_ptr
によって返されます。
名前
|
型
|
説明
|
initiating_loader | jobject |
起動クラス・ローダー。
initiating_loader がNULL の場合、ブートストラップ・ローダーによって起動されたクラスが返される。
|
class_count_ptr | jint* |
戻ったとき、クラスの数をポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
classes_ptr | jclass** |
戻ったとき、各クラスへの参照(クラスごとに1つずつ)の配列をポイントする。
エージェントはjclass* へのポインタを渡す。戻ったとき、jclass* は、サイズ*class_count_ptr の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。classes_ptr から返されるオブジェクトはJNIローカル参照であり、管理する必要がある。
|
クラスのシグニチャの取得
jvmtiError
GetClassSignature(jvmtiEnv* env,
jclass klass,
char** signature_ptr,
char** generic_ptr)
klass
で指定されたクラスに、JNI型のシグニチャとクラスのジェネリック・シグニチャを返します。たとえば、java.util.List
が"Ljava/util/List;"
で、int[]
が"[I"
の場合、返されるプリミティブ・クラスの名前は、対応するプリミティブ型の型シグニチャ文字になります。たとえば、java.lang.Integer.TYPE
は"I"
です。
名前
|
型
|
説明
|
klass | jclass |
照会するクラス。
|
signature_ptr | char ** |
戻ったとき、クラスのJNI型シグニチャ(修正UTF-8文字列としてエンコードされる)をポイントする。
エージェントはchar* へのポインタを渡す。戻り時に、char* は、新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。signature_ptr がNULL の場合、シグニチャは返されない。
|
generic_ptr | char ** |
戻ったとき、クラスのジェネリック・シグニチャ(修正UTF-8文字列としてエンコードされる)をポイントする。クラスのジェネリック・シグニチャ属性が存在しない場合は、戻ったときNULL をポイントする。
エージェントはchar* へのポインタを渡す。戻り時に、char* は、新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。generic_ptr がNULL の場合、ジェネリックス・シグニチャは返されない。
|
クラスのステータスの取得
jvmtiError
GetClassStatus(jvmtiEnv* env,
jclass klass,
jint* status_ptr)
クラスのステータスを取得します。次のビットのうち、0個以上のビットがセットされます。
定数
|
値
|
説明
|
JVMTI_CLASS_STATUS_VERIFIED | 1 |
クラスのバイト・コードが検証された。
|
JVMTI_CLASS_STATUS_PREPARED | 2 |
クラスの準備が完了した。
|
JVMTI_CLASS_STATUS_INITIALIZED | 4 |
クラスの初期化が完了した。静的な初期化子が実行された。
|
JVMTI_CLASS_STATUS_ERROR | 8 |
初期化中のエラーによりクラスが使用できない。
|
JVMTI_CLASS_STATUS_ARRAY | 16 |
クラスは配列。設定されている場合、その他のすべてのビットはゼロ。
|
JVMTI_CLASS_STATUS_PRIMITIVE | 32 |
クラスはプリミティブ・クラス(java.lang.Integer.TYPE など)。設定されている場合、その他のすべてのビットはゼロ。
|
名前
|
型
|
説明
|
klass | jclass |
照会するクラス。
|
status_ptr | jint* |
戻ったとき、このクラスの現在の状態としてクラスのステータス・フラグを1つ以上ポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
ソース・ファイル名の取得
jvmtiError
GetSourceFileName(jvmtiEnv* env,
jclass klass,
char** source_name_ptr)
klass
で指定されたクラスについて、source_name_ptr
を介してソース・ファイル名を返します。返される文字列は、ファイル名だけで、ディレクトリ名は含まれません。
プリミティブ・クラス(たとえば、java.lang.Integer.TYPE
)および配列の場合、この関数はJVMTI_ERROR_ABSENT_INFORMATION
を返します。
名前
|
型
|
説明
|
klass | jclass |
照会するクラス。
|
source_name_ptr | char** |
戻ったとき、クラスのソース・ファイル名(修正UTF-8文字列としてエンコードされる)をポイントする。
エージェントはchar* へのポインタを渡す。戻り時に、char* は、新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。 |
クラスの修飾子の取得
jvmtiError
GetClassModifiers(jvmtiEnv* env,
jclass klass,
jint* modifiers_ptr)
klass
で指定されたクラスのアクセス・フラグを、modifiers_ptr
を介して返します。アクセス・フラグは、Java(tm)仮想マシン仕様の第4章に定義されています。
クラスが配列クラスの場合、そのpublic、privateおよびprotected修飾子は、そのコンポーネント型の修飾子と同じです。プリミティブ型の配列の場合、このコンポーネント型は、プリミティブ・クラスの1つ(たとえば、java.lang.Integer.TYPE
)で表現されます。
クラスがプリミティブ・クラスの場合、そのpublic修飾子は常にtrueになります。また、そのprotected修飾子およびprivate修飾子は常にfalseになります。
クラスが配列クラスまたはプリミティブ・クラスの場合、そのfinal修飾子は常にtrueになり、interface修飾子は常にfalseになります。その他の修飾子の値は、この仕様では判定されません。
名前
|
型
|
説明
|
klass | jclass |
照会するクラス。
|
modifiers_ptr | jint* |
戻ったとき、このクラスの現在のアクセス・フラグをポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
クラスのメソッドの取得
jvmtiError
GetClassMethods(jvmtiEnv* env,
jclass klass,
jint* method_count_ptr,
jmethodID** methods_ptr)
klass
で指定されたクラスに含まれるメソッドの数をmethod_count_ptr
を介して返し、メソッドIDのリストをmethods_ptr
を介して返します。メソッドのリストには、本来のメソッドだけでなく、コンストラクタおよびstatic初期化子も含まれます。直接宣言されたメソッドだけが返されます(継承したメソッドは返されない)。配列クラスおよびプリミティブ・クラス(たとえば、java.lang.Integer.TYPE
)の場合、空のメソッド・リストが返されます。
名前
|
型
|
説明
|
klass | jclass |
照会するクラス。
|
method_count_ptr | jint* |
戻ったとき、このクラスで宣言されているメソッドの数をポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
methods_ptr | jmethodID** |
戻ったとき、メソッドIDの配列をポイントする。
エージェントはjmethodID* へのポインタを渡す。戻ったとき、jmethodID* は、サイズ*method_count_ptr の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。 |
クラスのフィールドの取得
jvmtiError
GetClassFields(jvmtiEnv* env,
jclass klass,
jint* field_count_ptr,
jfieldID** fields_ptr)
klass
で指定されたクラスに含まれるフィールドの数をfield_count_ptr
を介して返し、フィールドIDのリストをfields_ptr
を介して返します。直接宣言されたフィールドだけが返されます(継承したフィールドは返されない)。フィールドは、クラス・ファイル内に出現する順序で返されます。配列クラスおよびプリミティブ・クラス(たとえば、java.lang.Integer.TYPE
)の場合、空のフィールド・リストが返されます。JNIを使って、配列の長さを判別してください。
名前
|
型
|
説明
|
klass | jclass |
照会するクラス。
|
field_count_ptr | jint* |
戻ったとき、このクラスで宣言されているフィールドの数をポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
fields_ptr | jfieldID** |
戻ったとき、フィールドIDの配列をポイントする。
エージェントはjfieldID* へのポインタを渡す。戻ったとき、jfieldID* は、サイズ*field_count_ptr の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。 |
実装されたインタフェースの取得
jvmtiError
GetImplementedInterfaces(jvmtiEnv* env,
jclass klass,
jint* interface_count_ptr,
jclass** interfaces_ptr)
このクラスの直接のスーパー・インタフェースを返します。クラスに対しては、この関数は、implements
節で宣言されているインタフェースを返します。インタフェースに対しては、この関数は、extends
節で宣言されているインタフェースを返します。配列クラスおよびプリミティブ・クラス(たとえば、java.lang.Integer.TYPE
)の場合、空のインタフェース・リストが返されます。
名前
|
型
|
説明
|
klass | jclass |
照会するクラス。
|
interface_count_ptr | jint* |
戻ったとき、インタフェースの数をポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
interfaces_ptr | jclass** |
戻ったとき、インタフェースの配列をポイントする。
エージェントはjclass* へのポインタを渡す。戻ったとき、jclass* は、サイズ*interface_count_ptr の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。interfaces_ptr から返されるオブジェクトはJNIローカル参照であり、管理する必要がある。
|
クラス・バージョン番号の取得
jvmtiError
GetClassVersionNumbers(jvmtiEnv* env,
jclass klass,
jint* minor_version_ptr,
jint* major_version_ptr)
klass
に指定されたクラスについては、Java(tm)仮想マシン仕様の第4章で定義されているように、マイナー・バージョン番号とメジャー・バージョン番号を返します。
名前
|
型
|
説明
|
klass | jclass |
照会するクラス。
|
minor_version_ptr | jint* |
戻ったとき、クラス・ファイル形式のminor_version 項目の値をポイントする。注: クラス・ファイル形式との一貫性を保つために、マイナー・バージョン番号が最初のパラメータになっている。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
major_version_ptr | jint* |
戻ったとき、クラス・ファイル形式のmajor_version 項目の値をポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
定数プールの取得
jvmtiError
GetConstantPool(jvmtiEnv* env,
jclass klass,
jint* constant_pool_count_ptr,
jint* constant_pool_byte_count_ptr,
unsigned char** constant_pool_bytes_ptr)
klass
で示されたクラスについては、Java(tm)仮想マシン仕様の第4章に記載されたconstant_pool
項目の形式で定数プールのrawバイトを返します。定数プールの形式は、クラス・ファイル形式のバージョンによって異なる可能性があるので、クラスのメジャー・バージョン番号、マイナー・バージョン番号に互換性があることを確認するようにしてください。
返される定数プールのレイアウトや内容が、定義元のクラス・ファイル内の定数プールと同じでないこともあります。GetConstantPool()から返される定数プールのエントリ数は、定義元の定数プールのエントリ数と異なる場合があります。エントリの順序が異なる場合もあります。GetConstantPool()から返される定数プールは、GetBytecodes()が使用する定数プールに一致します。つまり、GetBytecodes()から返されるバイト・コードに含まれる定数プール・インデックスは、GetConstantPool()から返される定数プールのエントリを参照します。RetransformClasses
およびRedefineClasses
は定数プールを変更できるため、この関数から返される定数プールは、それに応じて変更される可能性があります。したがって、途中でクラスの再変換または再定義が行われた場合は、GetConstantPool()とGetBytecodes()の間の対応関係が維持されません。ある特定のバイト・コードが使用する定数プール・エントリの値は、定義元クラス・ファイルの対応する値に一致します(インデックスが一致しない場合でも)。バイト・コードが直接的にも間接的にも使用しない定数プール・エントリ(注釈に関連付けられているUTF-8文字列など)は、返された定数プール内に存在していなくてもかまいません。
名前
|
型
|
説明
|
klass | jclass |
照会するクラス。
|
constant_pool_count_ptr | jint* |
戻ったとき、定数プール・テーブル内のエントリの数+1をポイントする。これは、クラス・ファイル形式のconstant_pool_count 項目に対応している。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
constant_pool_byte_count_ptr | jint* |
戻ったとき、返されたraw定数プール内のバイト数をポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
constant_pool_bytes_ptr | unsigned char** |
戻ったとき、raw定数プールをポイントする。これは、クラス・ファイル形式のconstant_pool 項目で定義されたバイトになる。
エージェントはunsigned char* へのポインタを渡す。戻ったとき、unsigned char* は、サイズ*constant_pool_byte_count_ptr の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。 |
インタフェースかどうかの検査
jvmtiError
IsInterface(jvmtiEnv* env,
jclass klass,
jboolean* is_interface_ptr)
クラス・オブジェクト参照がインタフェースを表しているかどうかを判定します。クラスが実際にインタフェースである場合、jboolean
はJNI_TRUE
を返し、インタフェースではない場合にはJNI_FALSE
を返します。
名前
|
型
|
説明
|
klass | jclass |
照会するクラス。
|
is_interface_ptr | jboolean* |
戻ったとき、この関数のboolean型の結果をポイントする。
エージェントはjboolean へのポインタを渡す。戻ったとき、jboolean が設定されている。 |
配列クラスかどうかの検査
jvmtiError
IsArrayClass(jvmtiEnv* env,
jclass klass,
jboolean* is_array_class_ptr)
クラス・オブジェクト参照が配列を表しているかどうかを判定します。jboolean
は、クラスが配列である場合はJNI_TRUE
になり、そうでない場合はJNI_FALSE
になります。
名前
|
型
|
説明
|
klass | jclass |
照会するクラス。
|
is_array_class_ptr | jboolean* |
戻ったとき、この関数のboolean型の結果をポイントする。
エージェントはjboolean へのポインタを渡す。戻ったとき、jboolean が設定されている。 |
変更可能クラスかどうかの検査
jvmtiError
IsModifiableClass(jvmtiEnv* env,
jclass klass,
jboolean* is_modifiable_class_ptr)
クラスが変更可能かどうかを判定します。クラスが変更可能である場合(is_modifiable_class_ptr
がJNI_TRUE
を返した場合)、そのクラスは、RedefineClasses
を使って再定義したり(エージェントがcan_redefine_classes
権限を所有していると仮定)、RetransformClasses
を使って再変換したり(エージェントがcan_retransform_classes
権限を所有していると仮定)できます。あるクラスが変更不可能である場合(is_modifiable_class_ptr
がJNI_FALSE
を返した場合)、そのクラスは再定義することも再変換することもできません。
プリミティブ・クラス(java.lang.Integer.TYPE
など)と配列クラスが変更可能になることはありません。
名前
|
型
|
説明
|
klass | jclass |
照会するクラス。
|
is_modifiable_class_ptr | jboolean* |
戻ったとき、この関数のboolean型の結果をポイントする。
エージェントはjboolean へのポインタを渡す。戻ったとき、jboolean が設定されている。 |
クラス・ローダーの取得
jvmtiError
GetClassLoader(jvmtiEnv* env,
jclass klass,
jobject* classloader_ptr)
klass
で指定されたクラスのクラス・ローダーの参照を、classloader_ptr
を介して返します。
名前
|
型
|
説明
|
klass | jclass |
照会するクラス。
|
classloader_ptr | jobject* |
戻ったとき、このクラスをロードしたクラス・ローダーをポイントする。クラスがクラス・ローダーで作成されていない場合、またはクラス・ローダーがブートストラップ・クラス・ローダーでない場合は、NULL をポイントする。
エージェントはjobject へのポインタを渡す。戻ったとき、jobject が設定されている。classloader_ptr から返されるオブジェクトはJNIローカル参照であり、管理する必要がある。
|
ソース・デバッグ拡張機能の取得
jvmtiError
GetSourceDebugExtension(jvmtiEnv* env,
jclass klass,
char** source_debug_extension_ptr)
klass
で指定されたクラスのデバッグ拡張機能を、source_debug_extension_ptr
を介して返します。返される文字列には、klass
のクラス・ファイルに存在するデバッグ拡張情報がそのまま含まれます。
名前
|
型
|
説明
|
klass | jclass |
照会するクラス。
|
source_debug_extension_ptr | char** |
戻ったとき、クラスのデバッグ拡張機能(修正UTF-8文字列としてエンコードされる)をポイントする。
エージェントはchar* へのポインタを渡す。戻り時に、char* は、新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。 |
クラスの再変換
jvmtiError
RetransformClasses(jvmtiEnv* env,
jint class_count,
const jclass* classes)
この関数は、すでにロード済みのクラスのバイト・コード・インストゥルメンテーションを容易にします。修正しながらデバッグを続けるためにソースから再コンパイルする場合のように、既存のバイト・コードを参照することなしにクラス定義を置換する場合は、代わりにRedefineClasses
関数を使用するようにしてください。
クラスがはじめてロードされるときや再定義されるときに、その初期クラス・ファイル・バイトをClassFileLoadHook
イベント経由で変換することができます。この関数は、以前に変換が行われたかどうかには関係なく、変換処理を再実行します。この再変換は次の手順で行われます。
- 初期クラス・ファイル・バイトから処理が開始されます。
- 前回のロードまたは再定義時に
ClassFileLoadHook
イベントを受信した再変換不可能エージェントごとに、エージェントが(new_class_data
パラメータ経由で)返したバイトが変換の出力として再利用されます。これは、ClassFileLoadHook
イベントがこれらのエージェントに送信されない点を除けば、前回の変換を変更なしに再適用するのと等価です。
- 再変換可能エージェントごとに、
ClassFileLoadHook
イベントが送信されます。これにより、新しい変換を適用できるようになります。
- 変換されたクラス・ファイル・バイトがクラスの新しい定義としてインストールされます。
詳細は、ClassFileLoadHook
イベントを参照してください。
初期クラス・ファイル・バイトは、ClassLoader.defineClass
またはRedefineClasses
に渡されたバイト(変換適用前)を表しますが、両者が厳密に一致しない可能性もあります。定数プールが、GetConstantPool
で説明した点で異なる可能性があります。メソッドのバイトコード内の定数プール・インデックスは対応します。一部の属性が存在しない可能性があります。メソッドの順序など、順序が意味を持たない場合には、順序が維持されないことがあります。
再変換を行うと、新しいバージョンのメソッドがインストールされる可能性があります。古いバージョンのメソッドは廃止される可能性があります。以降の呼出しでは新しいバージョンのメソッドが使用されます。メソッドがアクティブなスタック・フレームを持つ場合、それらのアクティブなスタック・フレームは元のメソッド・バージョンのバイト・コードを引き続き実行します。
この関数により、一般的なJVMセマンティックスのもとで行われる以外の初期化は起こりません。つまり、クラスを再変換しても、そのクラスの初期化は実行されません。staticフィールドの値は、呼出し前の状態のままです。
スレッドを中断する必要はありません。
クラス内のブレークポイントは解除されます。
属性はすべて更新されます。
再変換されたクラスのインスタンスは影響を受けません。各フィールドは以前の値を維持します。インスタンス上のタグも影響を受けません。
この呼び出しへの応答として、ClassFileLoadHook
以外のイベントが送信されることはありません。
再変換では、メソッド本体、定数プール、属性を変更できます。再変換では、フィールドまたはメソッドの追加、削除、名前変更、メソッドのシグネチャの変更、修飾子の変更、継承の変更を行わないようにする必要があります。これらの制限は将来のバージョンで解除される可能性があります。未サポートの再変換が試みられた場合に返されるエラー・コードについては、後述のエラー戻り値の説明を参照してください。クラス・ファイルのバイトが検証またはインストールされるのは、それらのバイトがClassFileLoadHook
イベントのチェーンを通過した後なので、返されるエラー・コードは再変換の結果を反映したものになります。JVMTI_ERROR_NONE
以外のエラー・コードが返された場合、再変換対象のどのクラスについても、新しい定義がインストールされることはありません。この関数が(エラー・コードJVMTI_ERROR_NONE
で)復帰した場合は、再変換対象のすべてのクラスで新しい定義がインストールされます。
名前
|
型
|
説明
|
class_count | jint |
再変換されるクラスの数。
|
classes | const jclass* |
再変換されるクラスの配列。
エージェントはjclass のclass_count 要素の配列を渡す。 |
クラスの再定義
typedef struct {
jclass klass;
jint class_byte_count;
const unsigned char* class_bytes;
} jvmtiClassDefinition;
jvmtiError
RedefineClasses(jvmtiEnv* env,
jint class_count,
const jvmtiClassDefinition* class_definitions)
指定されたクラスはすべて、提供される定義に従って再定義されます。この関数は、あるクラスの定義を新しい定義で置き換える場合に使用されます(修正継続方式のデバッグで必要になる)。バイトコード・インストゥルメンテーションのように、既存のクラス・ファイル・バイトを変換する必要がある場合は、RetransformClasses
を使用すべきです。
再定義を行うと、新しいバージョンのメソッドがインストールされる可能性があります。古いバージョンのメソッドは廃止される可能性があります。以降の呼出しでは新しいバージョンのメソッドが使用されます。メソッドがアクティブなスタック・フレームを持つ場合、それらのアクティブなスタック・フレームは元のメソッド・バージョンのバイト・コードを引き続き実行します。スタック・フレームをリセットする必要がある場合は、廃止されたバージョンのメソッドを含むフレームを、PopFrame
を使用してポップします。
この関数により、一般的なJVMセマンティックスのもとで行われる以外の初期化は起こりません。つまり、クラスの再定義では、クラスの初期化子は実行されません。staticフィールドの値は、呼出し前の状態のままです。
スレッドを中断する必要はありません。
クラス内のブレークポイントは解除されます。
属性はすべて更新されます。
再定義されたクラスのインスタンスは影響を受けません。各フィールドは以前の値を維持します。インスタンス上のタグも影響を受けません。
この呼出しにこたえて、JVM TIイベントとしてクラス・ファイル・ロードフックが送信されます(有効な場合)。しかし、その他のJVM TIイベントは送信されません。
再定義では、メソッド本体、定数プール、属性を変更できます。再定義では、フィールドまたはメソッドの追加、削除、名前変更、メソッドのシグネチャの変更、修飾子の変更、継承の変更を行わないようにする必要があります。これらの制限は将来のバージョンで解除される可能性があります。未サポートの再定義が試みられた場合に返されるエラー・コードについては、後述のエラー戻り値の説明を参照してください。クラス・ファイルのバイトが検証またはインストールされるのは、それらのバイトがClassFileLoadHook
イベントのチェーンを通過した後なので、返されるエラー・コードは、class_definitions
に渡されたバイトに適用された変換の結果を反映したものになります。JVMTI_ERROR_NONE
以外のエラー・コードが返された場合、再定義対象のどのクラスについても、新しい定義がインストールされることはありません。この関数が(エラー・コードJVMTI_ERROR_NONE
で)復帰した場合は、再定義対象のすべてのクラスで新しい定義がインストールされます。
フィールド
|
型
|
説明
|
klass | jclass |
このクラスのクラス・オブジェクト
|
class_byte_count | jint |
定義するクラスのバイト数(下)
|
class_bytes | const unsigned char* |
クラスを定義するバイト(Java(tm)仮想マシン仕様の第4章を参照)
|
名前
|
型
|
説明
|
class_count | jint |
class_definitions で指定されたクラスの数
|
class_definitions | const jvmtiClassDefinition* |
新しいクラス定義の配列
エージェントはjvmtiClassDefinition のclass_count 要素の配列を渡す。 |
オブジェクト
オブジェクト関数:
オブジェクトの型:
オブジェクト・サイズの取得
jvmtiError
GetObjectSize(jvmtiEnv* env,
jobject object,
jlong* size_ptr)
object
で示されたオブジェクトについて、オブジェクトのサイズをsize_ptr
経由で返します。このサイズは、このオブジェクトにより消費されるストレージの容量の実装固有の近似値です。これは、オブジェクトのオーバーヘッドの一部または全部を含む可能性があるため、実装内での比較には役立ちますが、実装間の比較には役立ちません。この近似値は、JVMの単一呼出しの間に変わる可能性があります。
名前
|
型
|
説明
|
object | jobject |
照会するオブジェクト。
|
size_ptr | jlong* |
戻ったとき、オブジェクトのサイズ(バイト単位)をポイントする。
エージェントはjlong へのポインタを渡す。戻ったとき、jlong が設定されている。 |
オブジェクトのハッシュ・コードの取得
jvmtiError
GetObjectHashCode(jvmtiEnv* env,
jobject object,
jint* hash_code_ptr)
object
で示されたオブジェクトについて、ハッシュ・コードをhash_code_ptr
経由で返します。このハッシュ・コードを使えばオブジェクト参照のハッシュ・テーブルを保守できますが、その場合、一部の実装でパフォーマンスが大幅に低下する可能性があります。ほとんどの場合、オブジェクトに情報を関連付けるための手段としては、タグのほうが効率的です。この関数は、特定のオブジェクトに対し、その存続期間を通じて同じハッシュ・コード値を保証します。
名前
|
型
|
説明
|
object | jobject |
照会するオブジェクト。
|
hash_code_ptr | jint* |
戻ったとき、オブジェクトのハッシュ・コードをポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
オブジェクトのモニターの利用情報を取得
typedef struct {
jthread owner;
jint entry_count;
jint waiter_count;
jthread* waiters;
jint notify_waiter_count;
jthread* notify_waiters;
} jvmtiMonitorUsage;
jvmtiError
GetObjectMonitorUsage(jvmtiEnv* env,
jobject object,
jvmtiMonitorUsage* info_ptr)
オブジェクトのモニターに関する情報を取得します。jvmtiMonitorUsage
構造体のフィールドに、モニターの使用に関する情報が入ります。
フィールド
|
型
|
説明
|
owner | jthread |
このモニターを所有しているスレッド。このモニターが使用されていない場合はNULL
|
entry_count | jint |
このモニターを所有するスレッドがモニターを使用した回数
|
waiter_count | jint |
このモニターを所有する順番を待っているスレッドの数
|
waiters | jthread* |
waiter_count 待機スレッド
|
notify_waiter_count | jint |
このモニターから通知を受ける待機スレッドの数
|
notify_waiters | jthread* |
通知を待っているnotify_waiter_count スレッド
|
名前
|
型
|
説明
|
object | jobject |
照会するオブジェクト。
|
info_ptr | jvmtiMonitorUsage* |
戻ったとき、指定されたオブジェクトのモニター情報が入っている。
エージェントはjvmtiMonitorUsage へのポインタを渡す。戻ったとき、jvmtiMonitorUsage が設定されている。jvmtiMonitorUsage のフィールドowner で返されるオブジェクトはJNIローカル参照であり、管理する必要がある。jvmtiMonitorUsage のwaiters フィールドに返されるポインタは、新しく割り当てられた配列。この配列は、Deallocate を使って解放するべき。jvmtiMonitorUsage のフィールドwaiters で返されるオブジェクトはJNIローカル参照であり、管理する必要がある。jvmtiMonitorUsage のnotify_waiters フィールドに返されるポインタは、新しく割り当てられた配列。この配列は、Deallocate を使って解放するべき。jvmtiMonitorUsage のフィールドnotify_waiters で返されるオブジェクトはJNIローカル参照であり、管理する必要がある。
|
フィールド
フィールド関数:
フィールドの名前とシグニチャの取得
jvmtiError
GetFieldName(jvmtiEnv* env,
jclass klass,
jfieldID field,
char** name_ptr,
char** signature_ptr,
char** generic_ptr)
klass
とfield
で指定されたフィールドについて、名前をname_ptr
で返し、シグニチャをsignature_ptr
で返します。
フィールドのシグニチャはJNI仕様で定義されており、Java(tm)仮想マシン仕様のセクション4.3.2ではfield descriptors
と呼ばれています。
名前
|
型
|
説明
|
klass | jclass |
照会するフィールドのクラス。
|
field | jfieldID |
照会するフィールド。
|
name_ptr | char ** |
戻ったとき、フィールド名(修正UTF-8文字列としてエンコードされる)をポイントする。
エージェントはchar* へのポインタを渡す。戻り時に、char* は、新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。name_ptr がNULL の場合、名前は返されない。
|
signature_ptr | char ** |
戻ったとき、フィールドのシグニチャ(修正UTF-8文字列としてエンコードされる)をポイントする。
エージェントはchar* へのポインタを渡す。戻り時に、char* は、新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。signature_ptr がNULL の場合、シグニチャは返されない。
|
generic_ptr | char ** |
戻ったとき、フィールドのジェネリック・シグニチャ(修正UTF-8文字列としてエンコードされる)をポイントする。フィールドのジェネリック・シグニチャ属性が存在しない場合は、戻ったときNULL をポイントする。
エージェントはchar* へのポインタを渡す。戻り時に、char* は、新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。generic_ptr がNULL の場合、ジェネリックス・シグニチャは返されない。
|
フィールドの宣言クラスの取得
jvmtiError
GetFieldDeclaringClass(jvmtiEnv* env,
jclass klass,
jfieldID field,
jclass* declaring_class_ptr)
klass
とfield
で指定されたフィールドについて、そのフィールドを定義しているクラスをdeclaring_class_ptr
を介して返します。宣言しているクラスは、klass
、スーパー・クラス、または実装されたインタフェースのいずれかです。
名前
|
型
|
説明
|
klass | jclass |
照会するクラス。
|
field | jfieldID |
照会するフィールド。
|
declaring_class_ptr | jclass* |
戻ったとき、宣言するクラスをポイントする。
エージェントはjclass へのポインタを渡す。戻ったとき、jclass が設定されている。declaring_class_ptr から返されるオブジェクトはJNIローカル参照であり、管理する必要がある。
|
フィールドの修飾子の取得
jvmtiError
GetFieldModifiers(jvmtiEnv* env,
jclass klass,
jfieldID field,
jint* modifiers_ptr)
klass
とfield
で指定されたフィールドのアクセス・フラグを、modifiers_ptr
を介して返します。アクセス・フラグは、Java(tm)仮想マシン仕様の第4章に定義されています。
名前
|
型
|
説明
|
klass | jclass |
照会するクラス。
|
field | jfieldID |
照会するフィールド。
|
modifiers_ptr | jint* |
戻ったとき、アクセス・フラグをポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
合成フィールドかどうかの検査
jvmtiError
IsFieldSynthetic(jvmtiEnv* env,
jclass klass,
jfieldID field,
jboolean* is_synthetic_ptr)
klass
およびfield
で指定されたフィールドに対し、is_synthetic_ptr
を介してそのフィールドが合成であるかどうかを示す値を返します。合成フィールドはコンパイラによって生成されますが、元のソース・コード内には存在しません。
名前
|
型
|
説明
|
klass | jclass |
照会するフィールドのクラス。
|
field | jfieldID |
照会するフィールド。
|
is_synthetic_ptr | jboolean* |
戻ったとき、この関数のboolean型の結果をポイントする。
エージェントはjboolean へのポインタを渡す。戻ったとき、jboolean が設定されている。 |
メソッド
メソッド関数:
メソッドの型:
これらの関数は、あるメソッド(jmethodID
として表現)に関する情報を提供したり、メソッドの処理方法を設定したりします。
廃止メソッド
関数RetransformClasses
およびRedefineClasses
を呼び出すと、新しいバージョンのメソッドがインストールされます。元のメソッド・バージョンと新しいメソッド・バージョンが同等と見なされるのは、次のような場合です。
- 双方のメソッドのバイト・コードが同じ(定数プールのインデックスを除く)
- 参照定数が等しい。
新しいメソッド・バージョンと等価でない元のメソッド・バージョンは「廃止」と呼ばれ、新しいメソッドIDが割り当てられます。そして、元のメソッドIDは新しいメソッド・バージョンを指すようになります。廃止されたメソッドIDかどうかをテストするには、IsMethodObsolete
を使用します。
メソッドの名前とシグニチャの取得
jvmtiError
GetMethodName(jvmtiEnv* env,
jmethodID method,
char** name_ptr,
char** signature_ptr,
char** generic_ptr)
method
で指定されたメソッドの名前をname_ptr
を介して返し、メソッドのシグニチャをsignature_ptr
を介して返します。
メソッドのシグニチャはJNI仕様で定義されており、Java(tm)仮想マシン仕様のセクション4.3.3ではmethod descriptors
と呼ばれています。Java言語仕様に定義されたメソッドのシグニチャとは異なる点に注意してください。
名前
|
型
|
説明
|
method | jmethodID |
照会するメソッド。
|
name_ptr | char ** |
戻ったとき、メソッド名(修正UTF-8文字列としてエンコードされる)をポイントする。
エージェントはchar* へのポインタを渡す。戻り時に、char* は、新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。name_ptr がNULL の場合、名前は返されない。
|
signature_ptr | char ** |
戻ったとき、メソッド・シグニチャ(修正UTF-8文字列としてエンコードされる)をポイントする。
エージェントはchar* へのポインタを渡す。戻り時に、char* は、新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。signature_ptr がNULL の場合、シグニチャは返されない。
|
generic_ptr | char ** |
戻ったとき、メソッドのジェネリック・シグニチャ(修正UTF-8文字列としてエンコードされる)をポイントする。メソッドのジェネリック・シグニチャ属性が存在しない場合は、戻ったときNULL をポイントする。
エージェントはchar* へのポインタを渡す。戻り時に、char* は、新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。generic_ptr がNULL の場合、ジェネリックス・シグニチャは返されない。
|
メソッドの宣言クラスの取得
jvmtiError
GetMethodDeclaringClass(jvmtiEnv* env,
jmethodID method,
jclass* declaring_class_ptr)
method
で指定されたメソッドを定義するクラスを、declaring_class_ptr
を介して返します。
名前
|
型
|
説明
|
method | jmethodID |
照会するメソッド。
|
declaring_class_ptr | jclass* |
戻ったとき、宣言するクラスをポイントする。
エージェントはjclass へのポインタを渡す。戻ったとき、jclass が設定されている。declaring_class_ptr から返されるオブジェクトはJNIローカル参照であり、管理する必要がある。
|
メソッドの修飾子の取得
jvmtiError
GetMethodModifiers(jvmtiEnv* env,
jmethodID method,
jint* modifiers_ptr)
method
で指定されたメソッドのアクセス・フラグを、modifiers_ptr
を介して返します。アクセス・フラグは、Java(tm)仮想マシン仕様の第4章に定義されています。
名前
|
型
|
説明
|
method | jmethodID |
照会するメソッド。
|
modifiers_ptr | jint* |
戻ったとき、アクセス・フラグをポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
局所変数の取得
jvmtiError
GetMaxLocals(jvmtiEnv* env,
jmethodID method,
jint* max_ptr)
method
で指定されたメソッドによって使用される局所変数(呼出し時にメソッドにパラメータを渡すために使用される局所変数を含む)のスロット数を返します。
Java(tm)仮想マシン仕様のセクション4.7.3のmax_locals
の説明を参照してください。
名前
|
型
|
説明
|
method | jmethodID |
照会するメソッド。
|
max_ptr | jint* |
戻ったとき、局所変数のスロットの最大数をポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
引数のサイズの取得
jvmtiError
GetArgumentsSize(jvmtiEnv* env,
jmethodID method,
jint* size_ptr)
method
で指定されたメソッドの引数によって使用される局所変数のスロット数を、max_ptr
を介して返します。なお、2ワードの引数は、スロットを2つ使用します。
名前
|
型
|
説明
|
method | jmethodID |
照会するメソッド。
|
size_ptr | jint* |
戻ったとき、引数のスロットの数をポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
行番号テーブルの取得
typedef struct {
jlocation start_location;
jint line_number;
} jvmtiLineNumberEntry;
jvmtiError
GetLineNumberTable(jvmtiEnv* env,
jmethodID method,
jint* entry_count_ptr,
jvmtiLineNumberEntry** table_ptr)
method
で指定されたメソッドについて、ソース行番号のエントリから成るテーブルを返します。テーブルのサイズはentry_count_ptr
、テーブル自体はtable_ptr
を介して返されます。
名前
|
型
|
説明
|
method | jmethodID |
照会するメソッド。
|
entry_count_ptr | jint* |
戻ったとき、テーブル内のエントリの数をポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
table_ptr | jvmtiLineNumberEntry** |
戻ったとき、行番号テーブルのポインタをポイントする。
エージェントはjvmtiLineNumberEntry* へのポインタを渡す。戻ったとき、jvmtiLineNumberEntry* は、サイズ*entry_count_ptr の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。 |
メソッドの配置位置の取得
jvmtiError
GetMethodLocation(jvmtiEnv* env,
jmethodID method,
jlocation* start_location_ptr,
jlocation* end_location_ptr)
method
で指定されたメソッドについて、その開始アドレスと終了アドレスをstart_location_ptr
とend_location_ptr
を介して返します。従来のバイト・コード・インデックス・スキーマでは、start_location_ptr
は常にゼロを、end_location_ptr
は常にバイト・コードから1を引いた値をポイントします。
名前
|
型
|
説明
|
method | jmethodID |
照会するメソッド。
|
start_location_ptr | jlocation* |
戻ったとき、最初の位置をポイントする。位置情報が得られない場合は-1 をポイントする。情報が使用可能で、GetJLocationFormat からJVMTI_JLOCATION_JVMBCI が返される場合、これは常にゼロになる。
エージェントはjlocation へのポインタを渡す。戻ったとき、jlocation が設定されている。 |
end_location_ptr | jlocation* |
戻ったとき、最後の位置をポイントする。位置情報が得られない場合は-1 をポイントする。
エージェントはjlocation へのポインタを渡す。戻ったとき、jlocation が設定されている。 |
局所変数テーブルの取得
typedef struct {
jlocation start_location;
jint length;
char* name;
char* signature;
char* generic_signature;
jint slot;
} jvmtiLocalVariableEntry;
jvmtiError
GetLocalVariableTable(jvmtiEnv* env,
jmethodID method,
jint* entry_count_ptr,
jvmtiLocalVariableEntry** table_ptr)
局所変数の情報を返します。
フィールド
|
型
|
説明
|
start_location | jlocation |
この局所変数がはじめて有効になるコード配列インデックス(つまり、この局所変数はそこで値を持っていなければならない)。
|
length | jint |
この局所変数の有効部分の長さ。この局所変数が有効である最後のコード配列インデックスは、start_location+length になる。
|
name | char* |
局所変数名。修正UTF-8文字列としてエンコードされる。
|
signature | char* |
局所変数の型のシグネチャ。修正UTF-8文字列としてエンコードされる。このシグネチャの形式は、Java™仮想マシン仕様の4.3.2章で定義された形式と同じになる。
|
generic_signature | char* |
局所変数のジェネリック・シグネチャ。修正UTF-8文字列としてエンコードされる。ジェネリック型でないすべての局所変数について、このフィールドの値はNULL になる。
|
slot | jint |
局所変数のスロット。「局所変数」を参照。
|
名前
|
型
|
説明
|
method | jmethodID |
照会するメソッド。
|
entry_count_ptr | jint* |
戻ったとき、テーブル内のエントリの数をポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
table_ptr | jvmtiLocalVariableEntry** |
戻ったとき、局所変数テーブルのエントリの配列をポイントする。
エージェントはjvmtiLocalVariableEntry* へのポインタを渡す。戻ったとき、jvmtiLocalVariableEntry* は、サイズ*entry_count_ptr の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。jvmtiLocalVariableEntry のname フィールドに返されるポインタは、新しく割り当てられた配列。この配列は、Deallocate を使って解放するべき。jvmtiLocalVariableEntry のsignature フィールドに返されるポインタは、新しく割り当てられた配列。この配列は、Deallocate を使って解放するべき。jvmtiLocalVariableEntry のgeneric_signature フィールドに返されるポインタは、新しく割り当てられた配列。この配列は、Deallocate を使って解放するべき。 |
バイト・コードの取得
jvmtiError
GetBytecodes(jvmtiEnv* env,
jmethodID method,
jint* bytecode_count_ptr,
unsigned char** bytecodes_ptr)
method
で指定されたメソッドを実装するバイト・コードを返します。バイト・コードの数は、bytecode_count_ptr
を介して返されます。バイト・コード自体は、bytecodes_ptr
を介して返されます。
名前
|
型
|
説明
|
method | jmethodID |
照会するメソッド。
|
bytecode_count_ptr | jint* |
戻ったとき、バイト・コードの配列の長さをポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
bytecodes_ptr | unsigned char** |
戻ったとき、バイト・コード配列へのポインタをポイントする。
エージェントはunsigned char* へのポインタを渡す。戻ったとき、unsigned char* は、サイズ*bytecode_count_ptr の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。 |
ネイティブ・メソッドかどうかの検査
jvmtiError
IsMethodNative(jvmtiEnv* env,
jmethodID method,
jboolean* is_native_ptr)
method
で指定されたメソッドがネイティブ・メソッドかどうかを表す値を、is_native_ptr
を介して返します。
名前
|
型
|
説明
|
method | jmethodID |
照会するメソッド。
|
is_native_ptr | jboolean* |
戻ったとき、この関数のboolean型の結果をポイントする。
エージェントはjboolean へのポインタを渡す。戻ったとき、jboolean が設定されている。 |
合成メソッドかどうかの検査
jvmtiError
IsMethodSynthetic(jvmtiEnv* env,
jmethodID method,
jboolean* is_synthetic_ptr)
method
で指定されたメソッドが合成メソッドかどうかを表す値を、is_synthetic_ptr
を介して返します。合成メソッドは、コンパイラによって生成されますが、元のソース・コード内には存在しません。
名前
|
型
|
説明
|
method | jmethodID |
照会するメソッド。
|
is_synthetic_ptr | jboolean* |
戻ったとき、この関数のboolean型の結果をポイントする。
エージェントはjboolean へのポインタを渡す。戻ったとき、jboolean が設定されている。 |
廃棄されたメソッドかどうかの検査
jvmtiError
IsMethodObsolete(jvmtiEnv* env,
jmethodID method,
jboolean* is_obsolete_ptr)
メソッドIDが廃止メソッド・バージョンを参照しているかどうかを判定します。
名前
|
型
|
説明
|
method | jmethodID |
照会するメソッドID。
|
is_obsolete_ptr | jboolean* |
戻ったとき、この関数のboolean型の結果をポイントする。
エージェントはjboolean へのポインタを渡す。戻ったとき、jboolean が設定されている。 |
ネイティブ・メソッド接頭辞の設定
jvmtiError
SetNativeMethodPrefix(jvmtiEnv* env,
const char* prefix)
この関数は、名前に接頭辞を適用して再試行できるようにすることにより、ネイティブ・メソッド解決のエラー処理を変更します。これをClassFileLoadHookイベントと組み合わせて使用すれば、ネイティブ・メソッドの計測が可能になります。
ネイティブ・メソッドはバイト・コードを持たないので、直接計測できません。したがって、計測可能なネイティブでないメソッドでネイティブ・メソッドをラップする必要があります。たとえば次を考えます。
native boolean foo(int x);
これが次のようになるように、(ClassFileLoadHookイベントを使って)クラス・ファイルを変換できます。
boolean foo(int x) {
... record entry to foo ...
return wrapped_foo(x);
}
native boolean wrapped_foo(int x);
ここでfooは、接頭辞「wrapped_」が付加された実際のネイティブ・メソッドのラッパーになっています。ただし、「wrapped_」は既存のメソッドの名前の一部として使用されている可能性があるため、接頭辞としてはよい選択肢ではありません。「$$$MyAgentWrapped$$$_」のような接頭辞の方が適切ですが、そうするとこの例が読みにくくなってしまいます。
ラッパーによってネイティブ・メソッド呼出しのデータ収集が可能になりますが、次に問題となるのは、ラップされたメソッドとネイティブ実装との関連付けです。つまり、メソッドwrapped_foo
を次のようなネイティブ実装foo
に解決する必要があります。
Java_somePackage_someClass_foo(JNIEnv* env, jint x)
この関数を使えば、接頭辞を指定し、適切な解決が行われるようにできます。具体的には、標準の解決が失敗した場合に、接頭辞を考慮して再び解決が試みられます。解決方法は2つあります。JNI関数RegisterNatives
による明示的な解決と、通常の自動解決です。RegisterNatives
の場合、VMは次の関連付けを試みます。
method(foo) -> nativeImplementation(foo)
これに失敗すると、指定された接頭辞をメソッド名の先頭に追加して解決が再試行され、次のような正しい解決が得られます。
method(wrapped_foo) -> nativeImplementation(foo)
自動解決の場合、VMは次を試みます。
method(wrapped_foo) -> nativeImplementation(wrapped_foo)
これに失敗すると、指定された接頭辞を実装名から削除して解決が再試行され、次の正しい解決が得られます。
method(wrapped_foo) -> nativeImplementation(foo)
接頭辞が使用されるのは標準の解決が失敗した場合だけなので、ネイティブ・メソッドのラップは選択的に行えます。
各JVM TI環境は独立しており、それぞれが独自のバイト・コード変換を行えるため、複数の層のラッパーが適用される可能性があります。したがって、環境ごとに異なる接頭辞が必要になります。変換は順番に適用されるため、接頭辞を適用する場合、接頭辞は変換と同じ順番で適用されます。変換の適用順については、ClassFileLoadHook
イベントを参照してください。つまり、3つの環境がラッパーを適用した場合、foo
は$env3_$env2_$env1_foo
のようになります。しかし、たとえば2番目の環境がfoo
にラッパーを適用しなかった場合は、単に$env3_$env1_foo
となります。接頭辞のシーケンスを効率的に決定できるようにするため、途中の接頭辞は、そのネイティブでないラッパーが存在する場合にのみ適用されます。つまりこの例では、$env1_foo
がネイティブ・メソッドでなくても、$env1_foo
が存在するため$env1_
接頭辞が適用されます。
接頭辞は解決時に使用されますが、その解決はいつでも遅延される可能性があります。したがって、ネイティブ・メソッドの接頭辞は、対応する接頭辞付きのネイティブ・メソッドが存在しているかぎり、設定されたままにしておく必要があります。
名前
|
型
|
説明
|
prefix | const char * |
適用する接頭辞。修正UTF-8文字列としてエンコードされる。
エージェントは、char の配列を渡す。prefix がNULL の場合、この環境の既存の接頭辞が取り消される。
|
複数のネイティブ・メソッド接頭辞の設定
jvmtiError
SetNativeMethodPrefixes(jvmtiEnv* env,
jint prefix_count,
char** prefixes)
通常のエージェントの場合、SetNativeMethodPrefix
が、ネイティブ・メソッドの接頭辞設定に必要とされるすべての機能を提供します。複数の独立したクラス・ファイル変換を実行するメタエージェント(別の層のエージェントのプロキシとしてのエージェントなど)の場合、この関数を使うと、各変換に独自の接頭辞を割り当てることができます。接頭辞は、指定された順番で適用され、SetNativeMethodPrefix
で説明した、複数のJVM TI環境からの接頭辞の適用方法と同じ方法で処理されます。
以前の接頭辞はすべて置換されます。したがって、prefix_count
に0
を指定してこの関数を呼び出すと、この環境の接頭辞機能が無効になります。
SetNativeMethodPrefix
とこの関数が、接頭辞を設定するための2つの方法です。1つの接頭辞を指定してSetNativeMethodPrefix
を呼び出すのは、prefix_count
に1
を指定してこの関数を呼び出すのと同じです。NULL
を指定してSetNativeMethodPrefix
を呼び出すのは、prefix_count
に0
を指定してこの関数を呼び出すのと同じです。
名前
|
型
|
説明
|
prefix_count | jint |
適用する接頭辞の数。
|
prefixes | char ** |
この環境で適用する接頭辞。それぞれ修正UTF-8文字列としてエンコードされる。
|
rawモニター
rawモニター関数:
rawモニターの作成
jvmtiError
CreateRawMonitor(jvmtiEnv* env,
const char* name,
jrawMonitorID* monitor_ptr)
rawモニターを作成します。
名前
|
型
|
説明
|
name | const char* |
モニターを識別する名前。修正UTF-8文字列としてエンコードされる。
エージェントは、char の配列を渡す。 |
monitor_ptr | jrawMonitorID* |
戻ったとき、作成されたモニターをポイントする。
エージェントはjrawMonitorID へのポインタを渡す。戻ったとき、jrawMonitorID が設定されている。 |
rawモニターの破棄
jvmtiError
DestroyRawMonitor(jvmtiEnv* env,
jrawMonitorID monitor)
rawモニターを破棄します。破棄されるモニターがこのスレッドによって入力された場合、破棄される前に終了します。破棄されるモニターが別のスレッドによって入力された場合、エラーが返され、モニターの破棄は行われません。
rawモニターの開始
jvmtiError
RawMonitorEnter(jvmtiEnv* env,
jrawMonitorID monitor)
rawモニターの排他的所有権を取得します。同じスレッドで複数回モニターを入力することができます。スレッドは、モニターを入力回数分だけ終了する必要があります。モニターがOnLoad
(接続されたスレッドが生成される前)の段階で入力され、接続されたスレッドが生成された時点で終了していない場合、入力はメイン・スレッドで行われたと認識されます。
rawモニターの終了
jvmtiError
RawMonitorExit(jvmtiEnv* env,
jrawMonitorID monitor)
rawモニターの排他的所有権を解放します。
rawモニターの待機
jvmtiError
RawMonitorWait(jvmtiEnv* env,
jrawMonitorID monitor,
jlong millis)
rawモニターの通知を待ちます。
別のスレッドが指定されたrawモニターのRawMonitorNotify
またはRawMonitorNotifyAll
を呼び出すか、指定されたtimeoutが経過するまで、現在のスレッドを待機させます。
名前
|
型
|
説明
|
monitor | jrawMonitorID |
モニター
|
millis | jlong |
タイム・アウト(ミリ秒単位)。タイム・アウトがゼロの場合、実際の時間は考慮されず、スレッドは単に通知されるまで待機する。
|
rawモニターの通知
jvmtiError
RawMonitorNotify(jvmtiEnv* env,
jrawMonitorID monitor)
rawモニターを待機中の1つのスレッドに通知します。
rawモニターの通知(すべて)
jvmtiError
RawMonitorNotifyAll(jvmtiEnv* env,
jrawMonitorID monitor)
rawモニターを待機中のすべてのスレッドに通知します。
JNI関数の遮断
JNI関数の遮断関数:
Java Native Interface (JNI)関数テーブルの操作により、JNI関数呼出しの遮断および再送信の機能を提供します。『Java Native Interface仕様』の「JNI関数」の説明を参照してください。
次に、カウント参照の作成順にJNI呼び出しNewGlobalRef
を遮断する例を示します。
JNIEnv original_jni_Functions;
JNIEnv redirected_jni_Functions;
int my_global_ref_count = 0;
jobject
MyNewGlobalRef(JNIEnv *jni_env, jobject lobj) {
++my_global_ref_count;
return originalJNIFunctions->NewGlobalRef(env, lobj);
}
void
myInit() {
jvmtiError err;
err = (*jvmti_env)->GetJNIFunctionTable(jvmti_env, &original_jni_Functions);
if (err != JVMTI_ERROR_NONE) {
die();
}
err = (*jvmti_env)->GetJNIFunctionTable(jvmti_env, &redirected_jni_Functions);
if (err != JVMTI_ERROR_NONE) {
die();
}
redirectedJNIFunctions->NewGlobalRef = MyNewGlobalRef;
err = (*jvmti_env)->SetJNIFunctionTable(jvmti_env, redirected_jni_Functions);
if (err != JVMTI_ERROR_NONE) {
die();
}
}
myInit
を呼び出したあと、ユーザーのJNIコードが実行され、新しいグローバル参照を作成する呼出しが行われることがあります。この呼出しは、通常のJNI実装ではなく、myNewGlobalRef
に渡されます。データの収集後も通常のJNI関数を呼び出せるように、元の関数テーブルのコピーは保持されます。また、上書きされないJNI関数の動作は、通常どおりです。
JNI関数テーブルの設定
jvmtiError
SetJNIFunctionTable(jvmtiEnv* env,
const jniNativeInterface* function_table)
現在および将来のすべてのJNI環境のJNI関数テーブルを設定します。このため、将来のJNI呼出しはすべて、指定された関数に渡されます。この関数に渡す関数テーブルを取得するには、GetJNIFunctionTable
を使用します。この関数が有効になるためには、更新されたテーブル・エントリがJNIクライアントで使用される必要があります。このテーブルはconst
として定義されるため、コンパイラによっては最適化によってテーブルへのアクセス機能が除去され、その結果、この関数が無効になる可能性があります。テーブルはコピーされます。テーブルのローカル・コピーを変更しても、何の効果もありません。この関数の影響を受けるのは関数テーブルのみであり、環境の他の側面はすべて何の影響も受けません。前述の例を参照してください。
名前
|
型
|
説明
|
function_table | const jniNativeInterface * |
新しいJNI関数テーブルをポイントする。
エージェントはjniNativeInterface へのポインタを渡す。 |
JNI関数テーブルの取得
jvmtiError
GetJNIFunctionTable(jvmtiEnv* env,
jniNativeInterface** function_table)
JNI関数テーブルを取得します。JNI関数テーブルは、割り当てられたメモリーにコピーされます。SetJNIFunctionTable
が呼び出されていた場合、(元の関数テーブルではなく)変更後の関数テーブルが返されます。コピーされるのは関数テーブルのみであり、環境の他の側面はコピーされません。前述の例を参照してください。
名前
|
型
|
説明
|
function_table | jniNativeInterface ** |
戻ったとき、*function_table は新しく割り当てられたJNI関数テーブルのコピーをポイントする。
エージェントはjniNativeInterface* へのポインタを渡す。戻り時に、jniNativeInterface* は、新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。 |
イベント管理
イベント管理関数:
イベント管理の型:
イベント・コールバックの設定
jvmtiError
SetEventCallbacks(jvmtiEnv* env,
const jvmtiEventCallbacks* callbacks,
jint size_of_callbacks)
イベントごとに呼び出される関数を設定します。コールバックを指定するには、置換用の関数テーブルを提供します。関数テーブルはコピーされます。テーブルのローカル・コピーを変更しても、何の効果もありません。これはアトミックなアクションであり、一度にすべてのコールバックが設定されます。この関数を呼び出すまで、イベントは送信されません。エントリがNULL
の場合またはイベントがsize_of_callbacks
を超えている場合、イベントは送信されません。イベントの詳細は、このドキュメントの後のほうで説明します。イベントが送信されるためには、イベントを有効化し、そのコールバックを登録する必要があります。この関数とSetEventNotificationMode
の呼出し順序は、結果に影響を与えません。
名前
|
型
|
説明
|
callbacks | const jvmtiEventCallbacks * |
新しいイベント・コールバック。
エージェントはjvmtiEventCallbacks へのポインタを渡す。callbacks がNULL の場合、既存のコールバックは削除される。
|
size_of_callbacks | jint |
sizeof(jvmtiEventCallbacks) -- バージョン間の互換性を実現。
|
イベント通知モードの設定
typedef enum {
JVMTI_ENABLE = 1,
JVMTI_DISABLE = 0
} jvmtiEventMode;
jvmtiError
SetEventNotificationMode(jvmtiEnv* env,
jvmtiEventMode mode,
jvmtiEvent event_type,
jthread event_thread,
...)
イベントの生成を制御します。
thread
がNULL
の場合、イベントの有効化または無効化はグローバルに行われます。それ以外の場合、その有効化または無効化は特定のスレッドに対して行われます。あるイベントが特定のスレッドで生成されるのは、そのイベントがスレッド・レベル、グローバル・レベルのいずれかで有効化された場合です。
個々のイベントについての情報は、後述する説明を参照してください。
次のイベントは、この関数を使ってスレッド・レベルでは制御できません。
最初は、スレッド・レベルで有効にされているイベントも、グローバル・レベルで有効にされているイベントもありません。
この関数を呼び出す前に、必要な権限(後述の「イベントを有効化する権限」を参照)を所有している必要があります。
イベントの詳細については、後述します。
名前
|
型
|
説明
|
mode | jvmtiEventMode |
JVMTI_ENABLE またはJVMTI_DISABLE
|
event_type | jvmtiEvent |
制御するイベント
|
event_thread | jthread |
制御するスレッド
event_thread がNULL の場合、イベントはグローバル・レベルで制御される。
|
... | ... |
将来の拡張用
|
イベントの生成
jvmtiError
GenerateEvents(jvmtiEnv* env,
jvmtiEvent event_type)
VMの現在の状態を表すイベントを生成します。たとえば、event_type
がJVMTI_EVENT_COMPILED_METHOD_LOAD
の場合、現在コンパイル済のメソッドごとにCompiledMethodLoad
イベントが送信されます。過去にロードされたが現在はアンロード済であるようなメソッドは、送信されません。以前に送信されたイベントの履歴は、この関数で送信されるイベントに影響を与えません。たとえば、この関数を呼び出すたびに、現在コンパイル済のすべてのメソッドが送信されます。
エージェントがプログラムの実行開始後に接続されたことにより、イベントが失われた場合は、この関数を使って失われたイベントを生成できます。
Javaプログラミング言語コードまたはJNI関数の実行の試みは、この関数が復帰するまで一時停止される可能性があるので、どちらもイベント送信スレッドから呼び出すべきではありません。不足するイベントが送信されて処理され、復帰するまで、この関数は復帰しません。イベントは、発生元のスレッドとは別のスレッド上で送信される場合があります。SetEventCallbacks
でイベントのコールバックを設定し、SetEventNotificationMode
でイベントを有効化しないと、イベントは発生しません。要求されたイベントの一部または全部を生成するための情報がVMにもう残っていない場合、単にイベントが送信されず、エラーも返されません。
サポートされるイベントは次のとおりです。
名前
|
型
|
説明
|
event_type | jvmtiEvent |
生成するイベントのタイプ。次のいずれかとする。
|
拡張機能メカニズム
拡張機能メカニズム関数:
拡張機能メカニズムの関数型:
拡張機能メカニズムの型:
JVM TI実装は、これらの関数を使って、この仕様に定義されていない関数およびイベントを提供します。
拡張関数と拡張イベントのパラメータは、それぞれ次の表に示す「型」と「種類」を持ちます。
定数
|
値
|
説明
|
JVMTI_TYPE_JBYTE | 101 |
Javaプログラミング言語プリミティブ型 - byte 。JNI型jbyte 。
|
JVMTI_TYPE_JCHAR | 102 |
Javaプログラミング言語プリミティブ型 - char 。JNI型jchar 。
|
JVMTI_TYPE_JSHORT | 103 |
Javaプログラミング言語プリミティブ型 - short 。JNI型jshort 。
|
JVMTI_TYPE_JINT | 104 |
Javaプログラミング言語プリミティブ型 - int 。JNI型jint 。
|
JVMTI_TYPE_JLONG | 105 |
Javaプログラミング言語プリミティブ型 - long 。JNI型jlong 。
|
JVMTI_TYPE_JFLOAT | 106 |
Javaプログラミング言語プリミティブ型 - float 。JNI型jfloat 。
|
JVMTI_TYPE_JDOUBLE | 107 |
Javaプログラミング言語プリミティブ型 - double 。JNI型jdouble 。
|
JVMTI_TYPE_JBOOLEAN | 108 |
Javaプログラミング言語プリミティブ型 - boolean 。JNI型jboolean 。
|
JVMTI_TYPE_JOBJECT | 109 |
Javaプログラミング言語オブジェクト型 - java.lang.Object 。JNI型jobject 。戻り値はJNIローカル参照で、管理対象。
|
JVMTI_TYPE_JTHREAD | 110 |
Javaプログラミング言語オブジェクト型 - java.lang.Thread 。JVM TI型jthread 。戻り値はJNIローカル参照で、管理対象。
|
JVMTI_TYPE_JCLASS | 111 |
Javaプログラミング言語オブジェクト型 - java.lang.Class 。JNI型jclass 。戻り値はJNIローカル参照で、管理対象。
|
JVMTI_TYPE_JVALUE | 112 |
すべてのJavaプログラミング言語プリミティブ型およびオブジェクト型の和集合 - JNI型jvalue 。戻り値は、オブジェクト型がJNIローカル参照であることを表しており、管理対象。
|
JVMTI_TYPE_JFIELDID | 113 |
Javaプログラミング言語フィールド識別子 - JNI型jfieldID 。
|
JVMTI_TYPE_JMETHODID | 114 |
Javaプログラミング言語メソッド識別子 - JNI型jmethodID 。
|
JVMTI_TYPE_CCHAR | 115 |
Cプログラミング言語型 - char 。
|
JVMTI_TYPE_CVOID | 116 |
Cプログラミング言語型 - void 。
|
JVMTI_TYPE_JNIENV | 117 |
JNI環境 - JNIEnv 。ポインタ型にするには、適切なjvmtiParamKind とともに使用する必要がある。
|
定数
|
値
|
説明
|
JVMTI_KIND_IN | 91 |
入力引数 - foo 。
|
JVMTI_KIND_IN_PTR | 92 |
入力ポインタ引数 - const foo* 。
|
JVMTI_KIND_IN_BUF | 93 |
入力配列引数 - const foo* 。
|
JVMTI_KIND_ALLOC_BUF | 94 |
割当て済み出力配列引数 - foo** 。Deallocate で解放。
|
JVMTI_KIND_ALLOC_ALLOC_BUF | 95 |
割当て済み配列引数の割当て済み出力配列 - foo*** 。Deallocate で解放。
|
JVMTI_KIND_OUT | 96 |
出力引数 - foo* 。
|
JVMTI_KIND_OUT_BUF | 97 |
出力配列引数(エージェントにより事前に割当て済み) - foo* 。Deallocate は不可。
|
拡張関数/イベント・パラメータ情報
typedef struct {
char* name;
jvmtiParamKind kind;
jvmtiParamTypes base_type;
jboolean null_ok;
} jvmtiParamInfo;
拡張関数
typedef jvmtiError (JNICALL *jvmtiExtensionFunction)
(jvmtiEnv* jvmti_env,
...);
実装固有の拡張関数です。
名前
|
型
|
説明
|
jvmti_env | jvmtiEnv * |
JVM TI環境は、拡張関数の唯一の固定パラメータ。
|
... | ... |
拡張関数固有のパラメータ。
|
|
拡張関数の取得
typedef struct {
jvmtiExtensionFunction func;
char* id;
char* short_description;
jint param_count;
jvmtiParamInfo* params;
jint error_count;
jvmtiError* errors;
} jvmtiExtensionFunctionInfo;
jvmtiError
GetExtensionFunctions(jvmtiEnv* env,
jint* extension_count_ptr,
jvmtiExtensionFunctionInfo** extensions)
拡張関数のセットを返します。
名前
|
型
|
説明
|
extension_count_ptr | jint* |
戻ったとき、拡張関数の数をポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
extensions | jvmtiExtensionFunctionInfo** |
拡張関数情報の配列を、関数ごとに1つずつ返す。
エージェントはjvmtiExtensionFunctionInfo* へのポインタを渡す。戻ったとき、jvmtiExtensionFunctionInfo* は、サイズ*extension_count_ptr の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。jvmtiExtensionFunctionInfo のid フィールドに返されるポインタは、新しく割り当てられた配列。この配列は、Deallocate を使って解放するべき。jvmtiExtensionFunctionInfo のshort_description フィールドに返されるポインタは、新しく割り当てられた配列。この配列は、Deallocate を使って解放するべき。jvmtiExtensionFunctionInfo のparams フィールドに返されるポインタは、新しく割り当てられた配列。この配列は、Deallocate を使って解放するべき。jvmtiParamInfo のname フィールドに返されるポインタは、新しく割り当てられた配列。この配列は、Deallocate を使って解放するべき。jvmtiExtensionFunctionInfo のerrors フィールドに返されるポインタは、新しく割り当てられた配列。この配列は、Deallocate を使って解放するべき。 |
拡張イベントの取得
typedef struct {
jint extension_event_index;
char* id;
char* short_description;
jint param_count;
jvmtiParamInfo* params;
} jvmtiExtensionEventInfo;
jvmtiError
GetExtensionEvents(jvmtiEnv* env,
jint* extension_count_ptr,
jvmtiExtensionEventInfo** extensions)
拡張イベントのセットを返します。
フィールド
|
型
|
説明
|
extension_event_index | jint |
イベントを識別するインデックス
|
id | char* |
拡張イベントの識別子。修正UTF-8文字列としてエンコードされる。パッケージの命名規則を使用する。例: com.sun.hotspot.bar
|
short_description | char* |
イベントを1文で説明。修正UTF-8文字列としてエンコードされる。
|
param_count | jint |
jvmtiEnv *jvmti_env を除くパラメータ数
|
params | jvmtiParamInfo * |
param_count パラメータの配列(jvmtiEnv *jvmti_env は除外)
|
名前
|
型
|
説明
|
extension_count_ptr | jint* |
戻ったとき、拡張イベントの数をポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
extensions | jvmtiExtensionEventInfo** |
拡張イベント情報の配列を、イベントごとに1つずつ返す。
エージェントはjvmtiExtensionEventInfo* へのポインタを渡す。戻ったとき、jvmtiExtensionEventInfo* は、サイズ*extension_count_ptr の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。jvmtiExtensionEventInfo のid フィールドに返されるポインタは、新しく割り当てられた配列。この配列は、Deallocate を使って解放するべき。jvmtiExtensionEventInfo のshort_description フィールドに返されるポインタは、新しく割り当てられた配列。この配列は、Deallocate を使って解放するべき。jvmtiExtensionEventInfo のparams フィールドに返されるポインタは、新しく割り当てられた配列。この配列は、Deallocate を使って解放するべき。jvmtiParamInfo のname フィールドに返されるポインタは、新しく割り当てられた配列。この配列は、Deallocate を使って解放するべき。 |
拡張イベント
typedef void (JNICALL *jvmtiExtensionEvent)
(jvmtiEnv* jvmti_env,
...);
実装固有のイベントです。イベント・ハンドラの設定には、SetExtensionEventCallback を使用します。
拡張イベントのイベント・ハンドラは、この定義に一致するような宣言型の可変引数でなければなりません。宣言型の可変引数でない場合、一部のプラットフォームで、呼出し規則の不一致や未定義の動作が発生する可能性があります。
たとえば、GetExtensionEvents から返されたjvmtiParamInfo に、jint パラメータの存在が示されている場合、イベント・ハンドラを次のように宣言する必要があります。
void JNICALL myHandler(jvmtiEnv* jvmti_env, jint myInt, ...)
最後の「... 」は可変引数を表します。
名前
|
型
|
説明
|
jvmti_env | jvmtiEnv * |
JVM TI環境は、拡張イベントの唯一の固定パラメータ。
|
... | ... |
拡張イベント固有のパラメータ
|
|
拡張イベント・コールバックの設定
jvmtiError
SetExtensionEventCallback(jvmtiEnv* env,
jint extension_event_index,
jvmtiExtensionEvent callback)
拡張イベントにコールバック関数を設定し、イベントを有効にします。コールバックがNULL
の場合、イベントを無効にします。標準イベントとは異なり、コールバックを設定してイベントを有効にする処理は単一の操作です。
権限
権限関数:
権限の型:
権限関数では、JVM TIが使用できる機能(どのJVM TI関数を呼び出せるか、どんなイベントを生成できるか、これらのイベントや関数がどんな機能を提供できるかなど)を変更できます。
各関数およびイベントの「権限」のセクションには、関連付けられている権限の説明が記載されています(存在する場合)。「必要な機能」は、使用可能であり、権限を追加しなくても使用できることを表しています。「任意の機能」は、使用するためにはエージェントに権限が必要であることを表しています。権限を持つためには、エージェントは権限を追加する必要があります。「任意の機能」には、機能セットを拡張する権限の説明が記載されています。
各JVM TI実装が潜在的に使用できる権限は異なります。実装によって、次のようなことが言えます。
- 決して追加してはならない権限がある
- すべての環境で、ある権限を
OnLoad
またはライブ段階で追加できる
- ある権限を
OnLoad
段階でしか追加できない
- ある権限を複数の環境で同時に所有することはできない
- ある権限を複数の環境で同時に所有することはできない。また、
OnLoad
段階でしか所有できない
- その他。
しばしば、権限を追加することによって、実行速度、起動時間、メモリー・フットプリントなどに影響が出ることがあります。権限を使用するオーバーヘッドは、権限を所有するオーバーヘッドとはまったく異なる点に注意してください。例として、ステップ実行について考えてみましょう。ステップ実行が有効な場合は(イベントが有効で、アクティブにイベントを送信している状態)、どの実装でも、各命令でイベントを送信し、処理するオーバーヘッドが大きくなります。一方、権限を所有するオーバーヘッドは、実装によって大きかったり小さかったりします。また、権限を使用できるかどうか、および追加できるタイミングは、実装によって異なります。使用例を次に示します。
- あるVMは、バイト・コードをネイティブ・コードにコンパイルすることによってすべてを実行し、ステップ実行命令を生成できなくなっている。この実装では、権限は追加できない。
- 別のVMは、実行をステップ実行インタプリタにいつでも切り替えられる。この実装では、権限を所有することでオーバーヘッドは生じず、権限はいつでも追加できる。
- さらに別のVMは、バイトコード・コンパイル、シングル・ステップ実行可能な解釈実行エンジンのどちらかを起動時に選択できるが、両者間の切替えは行えない。この実装では、
OnLoad
段階(バイトコード実行の開始前)に権限を追加する必要があるほか、シングル・ステップ実行がまったく使用されなくても、権限が実行速度に大きな影響を与える。
- さらに別のVMは、コンパイル済みバイト・コードまたは生成済みインタプリタに「is single stepping on」チェックを追加できる。この実装でも、
OnLoad
段階で権限を追加する必要があるが、オーバーヘッド(各命令のテストとブランチ)はかなり低くなる。
各JVM TI環境は独自の権限セットを持ちます。最初、そのセットは空です。必要な権限をすべて追加する必要があります。権限の追加は、可能であればOnLoad
段階で行うべきです。ほとんどの仮想マシンでは、特定の権限には仮想マシンの特別な設定が必要であり、その設定は、仮想マシンの実行が開始される前にOnLoad
段階で行う必要があります。いったん追加された権限を削除できるのは、環境によって明示的に放棄された場合のみです。
エージェントは、このVMが潜在的に提供できる権限を特定し、使用する権限を追加し、不要になった権限を解放し、現在使用可能な権限を調べることができます。
権限の例
たとえば、OnLoad
関数で新規に起動したエージェントで、使用可能なすべての権限を有効にする場合があります。使用していない機能によってエージェントのパフォーマンスが低減する可能性があるため、一般にこの設定はお勧めしません。次に、Cで記述したコード例を示します。
jvmtiCapabilities capa;
jvmtiError err;
err = (*jvmti)->GetPotentialCapabilities(jvmti, &capa);
if (err == JVMTI_ERROR_NONE) {
err = (*jvmti)->AddCapabilities(jvmti, &capa);
たとえば、エージェントで、メソッドのバイト・コードを取得できるかどうかチェックする場合(以前にこの権限を追加して、まだ放棄していないかどうかをチェックする場合)、Cで記述したコードは次のようになります。
jvmtiCapabilities capa;
jvmtiError err;
err = (*jvmti)->GetCapabilities(jvmti, &capa);
if (err == JVMTI_ERROR_NONE) {
if (capa.can_get_bytecodes) { ... } }
権限の構造体
このカテゴリに含まれる関数は、次の権限構造体を使用します。この構造体には、各権限に対応するブール型フラグが含まれています。
typedef struct {
unsigned int can_tag_objects : 1;
unsigned int can_generate_field_modification_events : 1;
unsigned int can_generate_field_access_events : 1;
unsigned int can_get_bytecodes : 1;
unsigned int can_get_synthetic_attribute : 1;
unsigned int can_get_owned_monitor_info : 1;
unsigned int can_get_current_contended_monitor : 1;
unsigned int can_get_monitor_info : 1;
unsigned int can_pop_frame : 1;
unsigned int can_redefine_classes : 1;
unsigned int can_signal_thread : 1;
unsigned int can_get_source_file_name : 1;
unsigned int can_get_line_numbers : 1;
unsigned int can_get_source_debug_extension : 1;
unsigned int can_access_local_variables : 1;
unsigned int can_maintain_original_method_order : 1;
unsigned int can_generate_single_step_events : 1;
unsigned int can_generate_exception_events : 1;
unsigned int can_generate_frame_pop_events : 1;
unsigned int can_generate_breakpoint_events : 1;
unsigned int can_suspend : 1;
unsigned int can_redefine_any_class : 1;
unsigned int can_get_current_thread_cpu_time : 1;
unsigned int can_get_thread_cpu_time : 1;
unsigned int can_generate_method_entry_events : 1;
unsigned int can_generate_method_exit_events : 1;
unsigned int can_generate_all_class_hook_events : 1;
unsigned int can_generate_compiled_method_load_events : 1;
unsigned int can_generate_monitor_events : 1;
unsigned int can_generate_vm_object_alloc_events : 1;
unsigned int can_generate_native_method_bind_events : 1;
unsigned int can_generate_garbage_collection_events : 1;
unsigned int can_generate_object_free_events : 1;
unsigned int can_force_early_return : 1;
unsigned int can_get_owned_monitor_stack_depth_info : 1;
unsigned int can_get_constant_pool : 1;
unsigned int can_set_native_method_prefix : 1;
unsigned int can_retransform_classes : 1;
unsigned int can_retransform_any_class : 1;
unsigned int can_generate_resource_exhaustion_heap_events : 1;
unsigned int can_generate_resource_exhaustion_threads_events : 1;
unsigned int : 7;
unsigned int : 16;
unsigned int : 16;
unsigned int : 16;
unsigned int : 16;
unsigned int : 16;
} jvmtiCapabilities;
すべての型はunsigned int : 1 |
フィールド
|
説明
| 導入されたバージョン |
can_tag_objects | ヒープのカテゴリに説明されているように、タグを設定し、タグを取得できる。
| 1.0 |
can_generate_field_modification_events | フィールドの変更にウォッチポイントを設定できる - SetFieldModificationWatch
| 1.0 |
can_generate_field_access_events | フィールド・アクセスにウォッチポイントを設定できる - SetFieldAccessWatch
| 1.0 |
can_get_bytecodes | メソッドGetBytecodes のバイト・コードを取得できる
| 1.0 |
can_get_synthetic_attribute | フィールドまたはメソッドが合成であるかどうかをテストできる - IsFieldSynthetic とIsMethodSynthetic
| 1.0 |
can_get_owned_monitor_info | モニターの所有に関する情報を取得できる - GetOwnedMonitorInfo
| 1.0 |
can_get_current_contended_monitor | GetCurrentContendedMonitor が可能
| 1.0 |
can_get_monitor_info | GetObjectMonitorUsage が可能
| 1.0 |
can_pop_frame | スタックからフレームをポップできる - PopFrame
| 1.0 |
can_redefine_classes | RedefineClasses でクラスを再定義できる。
| 1.0 |
can_signal_thread | スレッドに停止または割込み信号を送信できる
| 1.0 |
can_get_source_file_name | クラスのソース・ファイルの名前を取得できる
| 1.0 |
can_get_line_numbers | メソッドの行番号テーブルを取得できる
| 1.0 |
can_get_source_debug_extension | クラスのソース・デバッグ拡張機能を取得できる
| 1.0 |
can_access_local_variables | 局所変数を設定し、取得できる
| 1.0 |
can_maintain_original_method_order | クラス・ファイル内に出現する順序でメソッドを返すことができる
| 1.0 |
can_generate_single_step_events | ステップ実行イベントを取得できる
| 1.0 |
can_generate_exception_events | スローされた例外イベントおよび例外キャッチイベントを取得できる
| 1.0 |
can_generate_frame_pop_events | FramePop イベントを設定し、取得できる
| 1.0 |
can_generate_breakpoint_events | Breakpoint イベントを設定し、取得できる
| 1.0 |
can_suspend | スレッドを中断し、再開できる
| 1.0 |
can_redefine_any_class | プリミティブ・クラスでも配列クラスでもない任意のクラスを変更(再変換または再定義)できる。IsModifiableClass を参照。
| 1.0 |
can_get_current_thread_cpu_time | 現在のスレッドCPU時間を取得できる
| 1.0 |
can_get_thread_cpu_time | スレッドCPU時間を取得できる
| 1.0 |
can_generate _method_entry_events | メソッドに入るときにメソッド・エントリ・イベントを生成できる
| 1.0 |
can_generate _method_exit_events | メソッドの終了時にメソッド終了イベントを生成できる
| 1.0 |
can_generate _all_class_hook_events | ロードされたすべてのクラスに対して、ClassFileLoadHookイベントを生成できる。
| 1.0 |
can_generate _compiled_method_load_events | メソッドのコンパイル時またはアンロード時にイベントを生成できる
| 1.0 |
can_generate _monitor_events | モニターの使用率に関するイベントを生成できる
| 1.0 |
can_generate _vm_object_alloc_events | オブジェクトのVM割当てに関するイベントを生成できる
| 1.0 |
can_generate _native_method_bind_events | ネイティブ・メソッドが実装にバインドされているときにイベントを生成できる
| 1.0 |
can_generate _garbage_collection_events | ガベージ・コレクションの開始時または終了時にイベントを生成できる
| 1.0 |
can_generate _object_free_events | ガベージ・コレクタがオブジェクトを解放するときにイベントを生成できる
| 1.0 |
can_force_early_return | 早期復帰の強制のカテゴリで説明しているように、メソッドから早期復帰できる。
| 1.1 |
can_get_owned_monitor_stack_depth_info | 所有されているモニターに関する情報とスタックの深さを取得できる - GetOwnedMonitorStackDepthInfo
| 1.1 |
can_get_constant_pool | あるクラスの定数プールを取得できる - GetConstantPool
| 1.1 |
can_set_native_method_prefix | ネイティブ・メソッドを解決できない場合に適用すべき接頭辞を設定できる - SetNativeMethodPrefix およびSetNativeMethodPrefixes
| 1.1 |
can_retransform_classes | RetransformClasses でクラスを再変換できる。特定の実装によって適用されるこの権限の制限(「権限」セクションを参照)に加え、この権限は、この環境でClassFileLoadHook イベントがはじめて有効化される前に設定する必要がある。ClassFileLoadHook がはじめて有効化された時点でこの権限を所有している環境を「再変換可能」と呼ぶ。ClassFileLoadHook がはじめて有効化された時点でこの権限を所有していない環境を「再変換不可能」と呼ぶ。
| 1.1 |
can_retransform_any_class | RetransformClasses を任意のクラスで呼び出せる(can_retransform_classes も設定する必要がある)
| 1.1 |
can_generate_resource_exhaustion_heap_events | VMがJavaTMプラットフォーム・ヒープからメモリーの割り当てを行えない場合に、イベントを生成できる。ResourceExhausted を参照。
| 1.1 |
can_generate_resource_exhaustion_threads_events | VMがスレッドを作成できない場合にイベントを生成できる。ResourceExhausted を参照。
| 1.1 |
潜在的な権限の取得
jvmtiError
GetPotentialCapabilities(jvmtiEnv* env,
jvmtiCapabilities* capabilities_ptr)
この時点でこの環境が所有できる可能性のあるJVM TI機能を、capabilities_ptr
経由で返します。返される権限が、VMに実装された完全な権限セットと異なる場合が2つあります。1つの環境しか所有できない権限を別の環境が所有している場合と、現在の段階がライブであり、OnLoad
段階でしか追加できない権限が存在している場合です。AddCapabilities
関数を使えば、これらの権限のいずれかまたはすべてを設定できます。現在所有されている権限が含まれます。
通常、この関数は、OnLoad
関数で使用されます。一部の仮想マシンでは、ライブ段階で追加できる権限のセットが制限されています。この場合、潜在的に使用可能な権限のセットが、OnLoad
段階のセットとは異なります。
権限の例を参照してください。
名前
|
型
|
説明
|
capabilities_ptr | jvmtiCapabilities* |
戻ったとき、追加可能なJVM TIの権限をポイントする。
エージェントはjvmtiCapabilities へのポインタを渡す。戻ったとき、jvmtiCapabilities が設定されている。 |
権限の追加
jvmtiError
AddCapabilities(jvmtiEnv* env,
const jvmtiCapabilities* capabilities_ptr)
*
capabilities_ptr
内で値が1
に設定されている権限を追加することで、新しい権限を設定します。以前の権限はすべて保持されます。通常、この関数は、OnLoad
関数で使用されます。一部の仮想マシンでは、ライブ段階で追加できる権限のセットが制限されています。
権限の例を参照してください。
名前
|
型
|
説明
|
capabilities_ptr | const jvmtiCapabilities* |
追加するJVM TI権限をポイントする。
エージェントはjvmtiCapabilities へのポインタを渡す。 |
権限の放棄
jvmtiError
RelinquishCapabilities(jvmtiEnv* env,
const jvmtiCapabilities* capabilities_ptr)
*
capabilities_ptr
内で値が1
に設定されている権限を放棄します。実装によっては、単一の環境にしか権限の所有が許可されない場合があります(権限の概要を参照)。この関数は、その他のエージェントが使用できるように、権限を解放します。その他のすべての権限は保持されます。権限は、GetCapabilities
からは失われます。エージェントが所有していない権限を放棄しようとしても、エラーは発生しません。
名前
|
型
|
説明
|
capabilities_ptr | const jvmtiCapabilities* |
放棄するJVM TI権限をポイントする。
エージェントはjvmtiCapabilities へのポインタを渡す。 |
権限の取得
jvmtiError
GetCapabilities(jvmtiEnv* env,
jvmtiCapabilities* capabilities_ptr)
capabilities_ptr
を介して、この環境が現在所有している任意のJVM TI機能を返します。所有している各権限は、権限構造体の対応するフィールドの1
によって示されます。環境は、AddCapabilities
を使って追加に成功するまで、権限を所有しません。環境は、RelinquishCapabilities
を使って放棄しないかぎり、権限を失いません。したがって、この関数は、AddCapabilities
呼び出しとRelinquishCapabilities
呼出しの最終結果を返します。
権限の例を参照してください。
名前
|
型
|
説明
|
capabilities_ptr | jvmtiCapabilities* |
戻ったとき、JVM TIの権限をポイントする。
エージェントはjvmtiCapabilities へのポインタを渡す。戻ったとき、jvmtiCapabilities が設定されている。 |
タイマー
タイマー関数:
タイマーの型:
これらの関数は、タイミング情報を提供します。時間が更新される精度は指定されていません。ナノ秒単位の精度が提供されますが、必ずしもナノ秒単位の精密度が得られるとはかぎりません。最大値など、タイマーの詳細情報には、タイマー情報関数を使ってアクセスできます。
タイマー情報
各タイマーの情報関数は、このデータ構造体を返します。
typedef struct {
jlong max_value;
jboolean may_skip_forward;
jboolean may_skip_backward;
jvmtiTimerKind kind;
jlong reserved1;
jlong reserved2;
} jvmtiTimerInfo;
フィールド
|
型
|
説明
|
max_value | jlong |
タイマーが到達できる最大値。この値に到達すると、タイマーの値はゼロに戻る。これは符号なしの値である。jlong (符号付きの値)としてテストまたは出力した場合、負の数値として表示される場合がある。
|
may_skip_forward | jboolean |
trueの場合、タイマーは外部で調整され、結果として前へスキップする。falseの場合、タイマーの値が実際の時間より速く増加することはない。
|
may_skip_backward | jboolean |
trueの場合、タイマーは外部で調整され、結果として後ろへスキップする。falseの場合、タイマーの値は一定して増加する。
|
kind | jvmtiTimerKind |
タイマーの種類。ユーザー・タイムとシステム・タイムを区別しないプラットフォームでは、JVMTI_TIMER_TOTAL_CPU が返される。
|
reserved1 | jlong |
将来の使用のために予約済み。
|
reserved2 | jlong |
将来の使用のために予約済み。
|
タイマーの種類は次のとおりです。
定数
|
値
|
説明
|
JVMTI_TIMER_USER_CPU | 30 |
スレッドがユーザー・モードであるCPU時間。
|
JVMTI_TIMER_TOTAL_CPU | 31 |
スレッドがユーザー・モードまたはシステム・モードであるCPU時間。
|
JVMTI_TIMER_ELAPSED | 32 |
経過時間。
|
現在のスレッドのCPUタイマー情報を取得
jvmtiError
GetCurrentThreadCpuTimerInfo(jvmtiEnv* env,
jvmtiTimerInfo* info_ptr)
GetCurrentThreadCpuTime
タイマーの情報を取得します。jvmtiTimerInfo
構造体のフィールドに、タイマーの詳細が入ります。この情報は、プラットフォームとGetCurrentThreadCpuTime
の実装に固有なので、スレッドごとに変化したり、VMの呼出し中に変化することはありません。
GetCurrentThreadCpuTime
とGetThreadCpuTime
の実装は異なることがあり、そのためにGetCurrentThreadCpuTimerInfo
とGetThreadCpuTimerInfo
によって返される値が異なることがあります。詳細については、GetCurrentThreadCpuTime
を参照してください。
現在のスレッドのCPU時間を取得
jvmtiError
GetCurrentThreadCpuTime(jvmtiEnv* env,
jlong* nanos_ptr)
現在のスレッドによって使用されているCPU時間を返します。
GetThreadCpuTime
関数は、現在のスレッドを含むあらゆるスレッドのCPU時間を提供します。GetCurrentThreadCpuTime
は、現在のスレッドまたは現在のスレッドよりも精密な情報を持つスレッド以外のスレッドのCPU時間を提供できないプラットフォームをサポートします(GetCurrentThreadCpuTimerInfo
とGetThreadCpuTimerInfo
を参照)。多くのプラットフォームでは、この呼出しは次のコードと同等です。
GetThreadCpuTime(env, NULL, nanos_ptr)
名前
|
型
|
説明
|
nanos_ptr | jlong* |
戻ったとき、このスレッドによって使用されるCPU時間(ナノ秒単位)をポイントする。これは符号なしの値である。jlong (符号付きの値)としてテストまたは出力した場合、負の数値として表示される場合がある。
エージェントはjlong へのポインタを渡す。戻ったとき、jlong が設定されている。 |
スレッドのCPUタイマー情報を取得
jvmtiError
GetThreadCpuTimerInfo(jvmtiEnv* env,
jvmtiTimerInfo* info_ptr)
GetThreadCpuTime
タイマーの情報を取得します。jvmtiTimerInfo
構造体のフィールドに、タイマーの詳細が入ります。この情報は、プラットフォームとGetThreadCpuTime
の実装に固有なので、スレッドごとに変化したり、VMの呼出し中に変化することはありません。
GetCurrentThreadCpuTime
とGetThreadCpuTime
の実装は異なることがあり、そのためにGetCurrentThreadCpuTimerInfo
とGetThreadCpuTimerInfo
によって返される値が異なることがあります。詳細については、GetCurrentThreadCpuTime
を参照してください。
スレッドのCPU時間を取得
jvmtiError
GetThreadCpuTime(jvmtiEnv* env,
jthread thread,
jlong* nanos_ptr)
指定のスレッドによって使用されているCPU時間を返します。
GetThreadCpuTimerInfo
により、このタイマーの情報を取得します。
任意の機能: すべての仮想マシンに実装することはないと考えられます。この関数を使用するためには、次の権限(GetCapabilities から返される)がtrueである必要があります。
|
権限
|
効果
|
can_get_thread_cpu_time |
スレッドCPU時間を取得できる。
この権限がスレッドの開始後に有効になった場合、実装は、権限が有効になった時間以降の任意の時間を、CPU時間の収集を開始するポイントとして選択できる。
|
名前
|
型
|
説明
|
thread | jthread |
照会するスレッド。thread がNULL の場合、現在のスレッドが使用される。
|
nanos_ptr | jlong* |
戻ったとき、指定されたスレッドによって使用されるCPU時間(ナノ秒単位)をポイントする。これは符号なしの値である。jlong (符号付きの値)としてテストまたは出力した場合、負の数値として表示される場合がある。
エージェントはjlong へのポインタを渡す。戻ったとき、jlong が設定されている。 |
タイマー情報の取得
jvmtiError
GetTimerInfo(jvmtiEnv* env,
jvmtiTimerInfo* info_ptr)
GetTime
タイマーの情報を取得します。jvmtiTimerInfo
構造体のフィールドに、タイマーの詳細が入ります。この情報は、VMの呼出し中に変更されません。
名前
|
型
|
説明
|
info_ptr | jvmtiTimerInfo* |
戻ったとき、GetTime によって返される時間を説明する情報が入っている。
エージェントはjvmtiTimerInfo へのポインタを渡す。戻ったとき、jvmtiTimerInfo が設定されている。 |
時間の取得
jvmtiError
GetTime(jvmtiEnv* env,
jlong* nanos_ptr)
システム・タイマーの現在の値(ナノ秒単位)を返します。
返される値は、固定された任意の時間からのナノ秒を表します(固定された任意の時間が将来の時間である場合は負の値になる)。この関数では、ナノ秒単位の精度が提供されますが、必ずしもナノ秒単位の精密度が得られるとはかぎりません。値の変更頻度は保証されません。
GetTimerInfo
により、このタイマーの情報を取得します。
名前
|
型
|
説明
|
nanos_ptr | jlong* |
戻ったとき、ナノ秒単位で時間をポイントする。これは符号なしの値である。jlong (符号付きの値)としてテストまたは出力した場合、負の数値として表示される場合がある。
エージェントはjlong へのポインタを渡す。戻ったとき、jlong が設定されている。 |
使用可能なプロセッサの取得
jvmtiError
GetAvailableProcessors(jvmtiEnv* env,
jint* processor_count_ptr)
Java仮想マシンが使用できるプロセッサの数を返します。
この値は、仮想マシンの呼出し中に変更される可能性があります。このため、使用可能なプロセッサの数に影響を受けるアプリケーションは、ときどきこのプロパティをポーリングする必要があります。
名前
|
型
|
説明
|
processor_count_ptr | jint* |
戻ったとき、仮想マシンが使用できる最大プロセッサ数をポイントする(必ず1以上)。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
クラス・ローダー検索
クラス・ローダー検索の関数:
これらの関数を使えば、エージェントは、クラス・ローダーがクラスを検索する際の場所を追加できます。これは、正しいクラス・ローダーでインストゥルメンテーションをインストールする際に便利です。
ブートストラップ・クラス・ローダー検索の追加
jvmtiError
AddToBootstrapClassLoaderSearch(jvmtiEnv* env,
const char* segment)
この関数では、ブートストラップ・クラス・ローダーを使用してインストゥルメンテーション・クラスを定義できます。Java(tm)仮想マシン仕様のセクション5.3.1を参照してください。ブートストラップ・クラス・ローダーによるクラスの検索が失敗すると、指定されたプラットフォーム依存の検索パスsegment
も検索されます。segment
に指定できるセグメントは1つのみです。この関数を複数回呼び出せば、複数のセグメントを追加できます。セグメントの検索は、この関数が呼び出された順番で行われます。
OnLoad
段階でこの関数を使うと、ブートストラップ・クラス・ローダーがクラスの検索に失敗した際に、追加で検索する任意のプラットフォーム依存の検索パス・セグメントを指定できます。このセグメントは通常、ディレクトリとJARファイルのいずれかになります。
ライブ段階でsegment
を使うと、任意のプラットフォーム依存のJARファイルへのパスを指定できます。ブートストラップ・クラス・ローダーがインストゥルメンテーション目的で定義するクラスやリソース以外のものがJARファイルに含まれないように、エージェントで確認するようにしてください。
Java(tm)仮想マシン仕様には、Java仮想マシンが以前にシンボリック参照を解決しようとして失敗した場合、その後このシンボリック参照を解決しようとしても、最初に解決しようとした結果としてスローされたエラーと同じエラーで必ず失敗すると記述されています。したがって、Java仮想マシンが参照を解決できなかったクラスに対応するエントリがJARファイルに含まれる場合、その参照を解決しようとしても最初のエラーと同じエラーで失敗します。
名前
|
型
|
説明
|
segment | const char* |
プラットフォーム依存の検索パス・セグメント、修正UTF-8文字列としてエンコードされる。
エージェントは、char の配列を渡す。 |
システム・クラス・ローダー検索の追加
jvmtiError
AddToSystemClassLoaderSearch(jvmtiEnv* env,
const char* segment)
この関数では、システム・クラス・ローダーを使用してインストゥルメンテーション・クラスを定義できます。Java(tm)仮想マシン仕様のセクション5.3.2を参照してください。クラス・ローダーによるクラスの検索が失敗すると、指定されたプラットフォーム依存の検索パスsegment
も検索されます。segment
に指定できるセグメントは1つのみです。この関数を複数回呼び出せば、複数のセグメントを追加できます。セグメントの検索は、この関数が呼び出された順番で行われます。
OnLoad
段階でこの関数を使うと、システム・クラス・ローダーがクラスの検索に失敗した際に、追加で検索する任意のプラットフォーム依存の検索パス・セグメントを指定できます。このセグメントは通常、ディレクトリとJARファイルのいずれかになります。
ライブ段階では、segment
は、システム・クラス・ローダーがクラスの検索に失敗した際に、追加で検索するプラットフォーム依存のJARファイルへのパスになります。システム・クラス・ローダーがインストゥルメンテーション目的で定義するクラスやリソース以外のものがJARファイルに含まれないように、エージェントで確認するようにしてください。
ライブ段階でシステム・クラス・ローダーが検索対象JARファイルの追加をサポートするのは、java.lang.String
型の単一パラメータを取るappendToClassPathForInstrumentation
という名前のメソッドをシステム・クラス・ローダーが実装している場合です。このメソッドは、public
アクセスを備えていなくてもかまいません。
Java(tm)仮想マシン仕様には、Java仮想マシンが以前にシンボリック参照を解決しようとして失敗した場合、その後このシンボリック参照を解決しようとしても、最初に解決しようとした結果としてスローされたエラーと同じエラーで必ず失敗すると記述されています。したがって、Java仮想マシンが参照を解決できなかったクラスに対応するエントリがJARファイルに含まれる場合、その参照を解決しようとしても最初のエラーと同じエラーで失敗します。
名前
|
型
|
説明
|
segment | const char* |
プラットフォーム依存の検索パス・セグメント、修正UTF-8文字列としてエンコードされる。
エージェントは、char の配列を渡す。 |
システム・プロパティ
システム・プロパティ関数:
これらの関数は、システム・プロパティを取得および設定します。
システム・プロパティの取得
jvmtiError
GetSystemProperties(jvmtiEnv* env,
jint* count_ptr,
char*** property_ptr)
GetSystemProperty
で使用可能なVMシステム・プロパティ・キーのリストが返されます。仮想マシンが次のプロパティ・キーを提供するようにすることを強くお勧めします。
-
java.vm.vendor
-
java.vm.version
-
java.vm.name
-
java.vm.info
-
java.library.path
-
java.class.path
VMによって定義され、使用されるシステム・プロパティへのアクセスを提供します。コマンド行で設定されたプロパティも含まれます。これにより、これらのプロパティを、VMがバイト・コードの実行を開始する前に取得、設定できます。これはシステム・プロパティのVMビューなので、使用可能なプロパティのセットは、通常、java.lang.System.getProperties
内のプロパティ・セットとは異なります。java.lang.System.getProperties
のアクセスには、JNIメソッド呼出しを使用できます。
プロパティのセットは、実行中に増えることがあります。
名前
|
型
|
説明
|
count_ptr | jint* |
戻ったとき、返されるプロパティ・キーの数をポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
property_ptr | char*** |
戻ったとき、プロパティ・キーの配列(修正UTF-8文字列としてエンコードされる)をポイントする。
エージェントはchar** へのポインタを渡す。char** は復帰時に、新しく割り当てられたサイズ*count_ptr の配列(各要素も新しく割り当てられる)をポイントしている。この配列は、Deallocate を使って解放するべき。各要素はDeallocate で解放すべき。 |
システム・プロパティの取得
jvmtiError
GetSystemProperty(jvmtiEnv* env,
const char* property,
char** value_ptr)
プロパティ・キーによって指定されたVMシステム・プロパティの値を返します。
関数GetSystemProperties
は、使用可能なプロパティ・キーのセットを返します。取得可能なプロパティは、実行中に増えることがあります。
これはシステム・プロパティのVMビューなので、プロパティの値は、java.lang.System.getProperty(String)
によって返されるプロパティの値とは異なります。通常のVMは、クラスの初期化中に、VMシステム・プロパティの値をjava.lang.System
に格納されているProperties
にコピーできます。その後、SetSystemProperty
を使用してVMシステム・プロパティを変更したり、java.lang.System.setProperty(String,String)
を使用してjava.lang.System
システム・プロパティを変更したりすると、値が変更されます。java.lang.System.getProperty(String)
のアクセスには、JNIメソッド呼出しを使用できます。
名前
|
型
|
説明
|
property | const char* |
取得されるプロパティのキー。修正UTF-8文字列としてエンコードされる。
エージェントは、char の配列を渡す。 |
value_ptr | char** |
戻ったとき、プロパティの値(修正UTF-8文字列としてエンコードされる)をポイントする。
エージェントはchar* へのポインタを渡す。戻り時に、char* は、新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。 |
システム・プロパティの設定
jvmtiError
SetSystemProperty(jvmtiEnv* env,
const char* property,
const char* value_ptr)
VMシステム・プロパティの値を設定します。
関数GetSystemProperties
は、プロパティ・キーのセットを返します。そのうちのいくつかは設定可能です。GetSystemProperty
を参照してください。
名前
|
型
|
説明
|
property | const char* |
プロパティのキー。修正UTF-8文字列としてエンコードされる。
エージェントは、char の配列を渡す。 |
value_ptr | const char * |
設定するプロパティ値。修正UTF-8文字列としてエンコードされる。
エージェントは、char の配列を渡す。value_ptr がNULL の場合は値が設定されないが、プロパティが書込み可能でない場合はJVMTI_ERROR_NOT_AVAILABLE が返される。
|
全般
全般関数:
全般の型:
全般のフラグおよび定数:
段階の取得
typedef enum {
JVMTI_PHASE_ONLOAD = 1,
JVMTI_PHASE_PRIMORDIAL = 2,
JVMTI_PHASE_START = 6,
JVMTI_PHASE_LIVE = 4,
JVMTI_PHASE_DEAD = 8
} jvmtiPhase;
jvmtiError
GetPhase(jvmtiEnv* env,
jvmtiPhase* phase_ptr)
VM実行の現在の段階を返します。段階は次の順で進行します。
定数
|
値
|
説明
|
JVMTI_PHASE_ONLOAD | 1 |
OnLoad 段階: Agent_OnLoad 関数内(静的リンク・エージェントの場合はAgent_OnLoad_<agent-lib-name> 関数内)の期間。
|
JVMTI_PHASE_PRIMORDIAL | 2 |
初期段階: Agent_OnLoad またはAgent_OnLoad_<agent-lib-name> から復帰してから、VMStart イベントが開始されるまでの間。
|
JVMTI_PHASE_START | 6 |
開始段階: VMStart イベントが送信されてからVMInit イベントが送信されるまで。
|
JVMTI_PHASE_LIVE | 4 |
ライブ段階: VMInit イベントが送信されてからVMDeath イベントが返されるまで。
|
JVMTI_PHASE_DEAD | 8 |
デッド段階: VMDeath イベントが返されてから、または起動に失敗してから。
|
起動に失敗した場合、VMは中間の段階を省略して直接デッド段階に進みます。この場合、VMInit
イベントもVMDeath
イベントも送信されません。
ほとんどのJVM TI関数は、ライブ段階でしか動作しません。次の関数は、OnLoad
段階でもライブ段階でも動作します。
次の関数は、OnLoad
段階でのみ動作します。
次の関数は、開始段階でもライブ段階でも動作します。
次の関数は、どの段階でも動作します。
JNI関数(呼び出しAPIを除く)は、開始段階またはライブ段階で使用する必要があります。
ほとんどのJVM TIイベントは、ライブ段階でしか送信されません。次のイベントは、その他の段階で扱われます。
名前
|
型
|
説明
|
phase_ptr | jvmtiPhase* |
戻ったとき、段階をポイントする。
エージェントはjvmtiPhase へのポインタを渡す。戻ったとき、jvmtiPhase が設定されている。 |
環境の破棄
jvmtiError
DisposeEnvironment(jvmtiEnv* env)
JNI GetEnv
で作成されたJVM TI接続をシャットダウンします(「JVM TI環境」を参照)。環境が保持していたリソースをすべて破棄します。この環境によって中断されたスレッドは、この呼出しによって再開されません。これはエージェントが明示的に行う必要があります。この環境によってJVM TI関数呼出し経由で割り当てられたメモリーは、解放されません。これをエージェントから明示的に行うには、Deallocate
を呼び出します。この環境によって作成されたrawモニターは破棄されません。これをエージェントから明示的に行うには、DestroyRawMonitor
を呼び出します。この環境によって作成されたrawモニター上で待機しているスレッドの状態は、何の影響も受けません。
この環境のネイティブ・メソッド接頭辞はすべて設定解除されます。エージェントは、破棄を呼び出す前に接頭辞付きネイティブ・メソッドをすべて削除しなければなりません。
この環境で保持されている権限はすべて放棄されます。
この環境で有効化されたイベントは送信されなくなりますが、現在実行中のイベント・ハンドラは引き続き実行されます。環境が破棄されたために実行中に無効になる可能性のあるイベント・ハンドラを設計する際には、十分に注意を払う必要があります。
この環境は、この呼出しのあとは使用できません。この呼出しは呼出し元に戻ります。
環境ローカル記憶領域の設定
jvmtiError
SetEnvironmentLocalStorage(jvmtiEnv* env,
const void* data)
VMは、個々の環境に関連付けられているポインタ値を格納します。このポインタ値を環境ローカルな記憶領域と呼びます。この関数で設定されない場合、値はNULL
になります。エージェントは、環境固有の情報を格納するため、メモリーを割り当てることができます。環境ローカルな記憶領域を設定することにより、GetEnvironmentLocalStorage
を使ってアクセスできるようになります。
JVM TIの環境ローカルな記憶領域の値を設定するため、エージェントによって呼び出されます。JVM TIは、エージェントに対して、環境ごとの情報を記録するために利用できる、ポインタ・サイズの環境ローカルな記憶領域を提供します。
名前
|
型
|
説明
|
data | const void * |
環境ローカルな記憶領域に入力する値。
エージェントがポインタを渡す。data がNULL の場合、値はNULL に設定される。
|
環境ローカル記憶領域の取得
jvmtiError
GetEnvironmentLocalStorage(jvmtiEnv* env,
void** data_ptr)
JVM TIの環境ローカルな記憶領域の値を取得するため、エージェントによって呼び出されます。
バージョン番号の取得
jvmtiError
GetVersionNumber(jvmtiEnv* env,
jint* version_ptr)
JVM TIのバージョンがversion_ptr
によって返されます。戻り値はバージョン識別子です。バージョン識別子には、インタフェースの型と、メジャー・バージョン番号、マイナー・バージョン番号、マイクロ・バージョン番号が含まれます。
定数
|
値
|
説明
|
JVMTI_VERSION_INTERFACE_JNI | 0x00000000 |
JNIのJVMTI_VERSION_MASK_INTERFACE_TYPE の値。
|
JVMTI_VERSION_INTERFACE_JVMTI | 0x30000000 |
JVM TIのJVMTI_VERSION_MASK_INTERFACE_TYPE の値。
|
定数
|
値
|
説明
|
JVMTI_VERSION_MASK_INTERFACE_TYPE | 0x70000000 |
マスクにより、インタフェースの型を抽出する。これはJVM TI関数なので、JVMTI_VERSION_MASK_INTERFACE_TYPE でマスクされた、この関数によって返されるバージョンの値は、常にJVMTI_VERSION_INTERFACE_JVMTI 。
|
JVMTI_VERSION_MASK_MAJOR | 0x0FFF0000 |
マスクにより、メジャー・バージョン番号を抽出する。
|
JVMTI_VERSION_MASK_MINOR | 0x0000FF00 |
マスクにより、マイナー・バージョン番号を抽出する。
|
JVMTI_VERSION_MASK_MICRO | 0x000000FF |
マスクにより、マイクロ・バージョン番号を抽出する。
|
定数
|
値
|
説明
|
JVMTI_VERSION_SHIFT_MAJOR | 16 |
シフトにより、メジャー・バージョン番号を抽出する。
|
JVMTI_VERSION_SHIFT_MINOR | 8 |
シフトにより、マイナー・バージョン番号を抽出する。
|
JVMTI_VERSION_SHIFT_MICRO | 0 |
シフトにより、マイクロ・バージョン番号を抽出する。
|
名前
|
型
|
説明
|
version_ptr | jint* |
戻ったとき、JVM TIのバージョンをポイントする。
エージェントはjint へのポインタを渡す。戻ったとき、jint が設定されている。 |
エラー名の取得
jvmtiError
GetErrorName(jvmtiEnv* env,
jvmtiError error,
char** name_ptr)
エラー・コードのシンボリック名を返します。
たとえば、GetErrorName(env, JVMTI_ERROR_NONE,&err_name)
は、err_name
に文字列"JVMTI_ERROR_NONE"
を返します。
名前
|
型
|
説明
|
error | jvmtiError |
エラー・コード。
|
name_ptr | char** |
戻ったとき、エラー名をポイントする。名前は、修正UTF-8文字列としてエンコードされるが、ASCIIサブセットに制限される。
エージェントはchar* へのポインタを渡す。戻り時に、char* は、新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放するべき。 |
冗長フラグの設定
typedef enum {
JVMTI_VERBOSE_OTHER = 0,
JVMTI_VERBOSE_GC = 1,
JVMTI_VERBOSE_CLASS = 2,
JVMTI_VERBOSE_JNI = 4
} jvmtiVerboseFlag;
jvmtiError
SetVerboseFlag(jvmtiEnv* env,
jvmtiVerboseFlag flag,
jboolean value)
定数
|
値
|
説明
|
JVMTI_VERBOSE_OTHER | 0 |
冗長出力(以下を除く)。
|
JVMTI_VERBOSE_GC | 1 |
冗長ガベージ・コレクタ出力(-verbose:gc で指定されたものと同様)。
|
JVMTI_VERBOSE_CLASS | 2 |
冗長クラス・ロード出力(-verbose:class で指定されたものと同様)。
|
JVMTI_VERBOSE_JNI | 4 |
冗長JNI出力(-verbose:jni で指定されたものと同様)。
|
冗長出力を制御します。これは、通常stderr
に送信される出力です。
JLocation形式の取得
typedef enum {
JVMTI_JLOCATION_JVMBCI = 1,
JVMTI_JLOCATION_MACHINEPC = 2,
JVMTI_JLOCATION_OTHER = 0
} jvmtiJlocationFormat;
jvmtiError
GetJLocationFormat(jvmtiEnv* env,
jvmtiJlocationFormat* format_ptr)
仮想マシンのバイト・コード・インデックスを参照する位置情報から最大の機能が得られますが、jlocation
の定義は、この情報を持たないVM実装を許可するため、意図的に制約を受けていません。
この関数は、このVMで使用されるjlocation
の表現を説明します。返される形式がJVMTI_JLOCATION_JVMBCI
の場合、jlocation
を、GetBytecodes
から返される配列のインデックスとして使用できます。
定数
|
値
|
説明
|
JVMTI_JLOCATION_JVMBCI | 1 |
jlocation の値は、仮想マシンのバイト・コード・インデックスを表す。つまり、メソッドの仮想マシン・コードのオフセット。
|
JVMTI_JLOCATION_MACHINEPC | 2 |
jlocation の値は、ネイティブ・マシンのプログラム・カウンタ値を表す。
|
JVMTI_JLOCATION_OTHER | 0 |
jlocation の値は、その他の表現を持つ。
|
名前
|
型
|
説明
|
format_ptr | jvmtiJlocationFormat* |
戻ったとき、jlocation 値の形式識別子をポイントする。
エージェントはjvmtiJlocationFormat へのポインタを渡す。戻ったとき、jvmtiJlocationFormat が設定されている。 |
エラー
JVM TI関数はすべて、jvmtiError
エラー・コードを返します。
エージェントは、有効なパラメータを持つJVM TI関数を、適切なコンテキスト(たとえば、呼出し側スレッドが接続されていて、段階が適切)で呼び出します。実装によって、一部のエラー条件の検出が困難であったり、非効率的であったり、不可能であったりします。実装は、「関数固有の必須エラー」に一覧されているエラーを検出する必要があります。その他のエラーは、エラー条件に対する推奨されている応答を表します。
汎用エラー
次のエラーは、どの関数からも返される可能性があるエラーです。
-
JVMTI_ERROR_NONE (0)
-
エラーは発生しなかった。関数の実行が正常に終了したときに返されるエラー・コード。
-
JVMTI_ERROR_NULL_POINTER (100)
-
ポインタが
NULL
。
-
JVMTI_ERROR_OUT_OF_MEMORY (110)
-
関数でメモリーの割当てが試行されたが、これ以上割り当てられるメモリーがなかった。
-
JVMTI_ERROR_ACCESS_DENIED (111)
-
この仮想マシンでは必要な機能が有効になっていない。
-
JVMTI_ERROR_UNATTACHED_THREAD (115)
-
この関数の呼出しに使われているスレッドが、仮想マシンに接続されていない。呼出しは、接続されたスレッドから行う必要がある。JNI呼び出しAPIの
AttachCurrentThread
を参照。
-
JVMTI_ERROR_INVALID_ENVIRONMENT (116)
-
指定されたJVM TI環境はもう接続されていない、または環境ではない。
-
JVMTI_ERROR_WRONG_PHASE (112)
-
現在の段階では、必要な機能を使用できない。仮想マシンが実行を完了している場合、常に返される。
-
JVMTI_ERROR_INTERNAL (113)
-
予期しない内部エラーが発生した。
関数固有の必須エラー
一部のJVM TI関数は、次のエラーを返します。これらのエラーは、条件が満たされたとき、実装によって返される必要があります。
-
JVMTI_ERROR_INVALID_PRIORITY (12)
-
無効な優先順位。
-
JVMTI_ERROR_THREAD_NOT_SUSPENDED (13)
-
スレッドは中断されていない。
-
JVMTI_ERROR_THREAD_SUSPENDED (14)
-
スレッドはすでに中断されている。
-
JVMTI_ERROR_THREAD_NOT_ALIVE (15)
-
この操作を行うには、スレッドが活動中(開始され、まだ終了していない)でなければならない。
-
JVMTI_ERROR_CLASS_NOT_PREPARED (22)
-
クラスがロードされているが、まだ準備されていない。
-
JVMTI_ERROR_NO_MORE_FRAMES (31)
-
指定された深さに、Javaプログラミング言語またはJNIスタック・フレームが存在しない。
-
JVMTI_ERROR_OPAQUE_FRAME (32)
-
フレームの情報が入手できない(ネイティブ・フレームの場合など)。
-
JVMTI_ERROR_DUPLICATE (40)
-
すでに設定された項目。
-
JVMTI_ERROR_NOT_FOUND (41)
-
目的の要素(フィールドやブレークポイントなど)が見つからない。
-
JVMTI_ERROR_NOT_MONITOR_OWNER (51)
-
このスレッドはrawモニターを所有していない。
-
JVMTI_ERROR_INTERRUPT (52)
-
呼出しの完了前に割り込まれた。
-
JVMTI_ERROR_UNMODIFIABLE_CLASS (79)
-
クラスは変更できない。
-
JVMTI_ERROR_NOT_AVAILABLE (98)
-
この機能はこの仮想マシンでは使用できない。
-
JVMTI_ERROR_ABSENT_INFORMATION (101)
-
要求された情報が入手できない。
-
JVMTI_ERROR_INVALID_EVENT_TYPE (102)
-
指定されたイベント・タイプのIDが認識されない。
-
JVMTI_ERROR_NATIVE_METHOD (104)
-
要求された情報がネイティブ・メソッドで使用できない。
-
JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED (106)
-
クラス・ローダーがこの操作をサポートしない。
関数固有のエージェント・エラー
次のエラーは、一部のJVM TI関数から返される可能性があるエラーです。これらのエラーは、エージェントによって無効なパラメータが渡された場合や、無効なコンテキストで使用された場合に返されます。これらのエラーは、実装なしで検出できます。
-
JVMTI_ERROR_INVALID_THREAD (10)
-
渡されたスレッドは有効なスレッドではない。
-
JVMTI_ERROR_INVALID_FIELDID (25)
-
無効なフィールド。
-
JVMTI_ERROR_INVALID_METHODID (23)
-
無効なメソッド。
-
JVMTI_ERROR_INVALID_LOCATION (24)
-
無効な位置。
-
JVMTI_ERROR_INVALID_OBJECT (20)
-
無効なオブジェクト。
-
JVMTI_ERROR_INVALID_CLASS (21)
-
無効なクラス。
-
JVMTI_ERROR_TYPE_MISMATCH (34)
-
使用した関数と変数の型が合わない。
-
JVMTI_ERROR_INVALID_SLOT (35)
-
無効なスロット。
-
JVMTI_ERROR_MUST_POSSESS_CAPABILITY (99)
-
この環境で使用される権限がfalse。
-
JVMTI_ERROR_INVALID_THREAD_GROUP (11)
-
スレッド・グループが無効。
-
JVMTI_ERROR_INVALID_MONITOR (50)
-
無効なrawモニター。
-
JVMTI_ERROR_ILLEGAL_ARGUMENT (103)
-
不正な引数。
-
JVMTI_ERROR_INVALID_TYPESTATE (65)
-
スレッドの状態が変更されたため、不整合が生じている。
-
JVMTI_ERROR_UNSUPPORTED_VERSION (68)
-
新しいクラス・ファイルのバージョンがこのVMでサポートされていない。
-
JVMTI_ERROR_INVALID_CLASS_FORMAT (60)
-
新しいクラス・ファイルの形式が正しくない(VMは
ClassFormatError
を返す)。
-
JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION (61)
-
新しいクラス・ファイルの定義が循環定義になる(VMは
ClassCircularityError
を返す)。
-
JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED (63)
-
新しいクラス・ファイルでメソッドの追加が必要。
-
JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED (64)
-
新しいクラスのバージョンによってフィールドが変更される。
-
JVMTI_ERROR_FAILS_VERIFICATION (62)
-
クラス・バイトが検証に失敗する。
-
JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED (66)
-
新しいクラスのバージョンの直接スーパー・クラスが異なる、または直接実装されているインタフェースが異なる。
-
JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED (67)
-
新しいクラスのバージョンでは旧クラスのバージョンで宣言したメソッドを宣言しない。
-
JVMTI_ERROR_NAMES_DONT_MATCH (69)
-
新しいクラス・ファイル内で定義されたクラス名が、旧クラス・オブジェクト内の名前と異なる。
-
JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED (70)
-
新しいクラスのバージョンの修飾子が異なる。
-
JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED (71)
-
新しいクラスのバージョンのメソッドの修飾子が旧クラスのバージョンの修飾子と異なる。
データ型
JVM TIは、JNIによって定義されたデータ型を拡張します。
型
|
説明
|
jboolean | Javaプログラミング言語boolean を保持します。符号なし8ビット。
|
jchar | Javaプログラミング言語char を保持します。符号なし16ビット。
|
jint | Javaプログラミング言語int を保持します。符号付き32ビット。
|
jlong | Javaプログラミング言語long を保持します。符号付き64ビット。
|
jfloat | Javaプログラミング言語float を保持します。32ビット。
|
jdouble | Javaプログラミング言語double を保持します。64ビット。
|
jobject | Javaプログラミング言語オブジェクトを保持する。
|
jclass | Javaプログラミング言語クラスを保持する。
|
jvalue | すべてのプリミティブ型およびjobject の和集合である。つまり、Javaプログラミング言語の任意の値を保持する。
|
jfieldID | Javaプログラミング言語のフィールドを識別する。JVM TIの関数やイベントから返されたjfieldID は、安全に格納できる。
|
jmethodID | Javaプログラミング言語メソッド、イニシャライザ、またはコンストラクタを識別する。JVM TIの関数やイベントから返されたjmethodID は、安全に格納できる。ただし、クラスがアンロードされた場合、それらは無効になるので使用してはいけない。
|
JNIEnv | JNI関数テーブルのポインタ。JNIEnv * のポインタはJNI環境。
|
型
|
説明
|
jvmtiEnv | JVM TI環境のポインタ。「関数」セクションを参照。jvmtiEnv は関数テーブルのポインタをポイントする。
|
jthread | スレッドを保持するjobject のサブタイプ。
|
typedef jobject jthread;
|
jthreadGroup | スレッド・グループを保持するjobject のサブタイプ。
|
typedef jobject jthreadGroup;
|
jlocation | メソッド内の単調に増加する実行可能位置を表す64ビット値。-1 はネイティブ・メソッドを示す。ある特定のVMでの形式については、GetJLocationFormat を参照。
|
typedef jlong jlocation;
|
jrawMonitorID | rawモニター。
|
struct _jrawMonitorID;
typedef struct _jrawMonitorID *jrawMonitorID;
|
jvmtiError | 戻りエラー・コードを保持する。可能な値については、「エラー」を参照。
typedef enum {
JVMTI_ERROR_NONE = 0,
JVMTI_ERROR_INVALID_THREAD = 10,
...
} jvmtiError;
|
jvmtiEvent | イベント・タイプの識別子。可能な値については、「イベント」を参照。この仕様の将来のバージョンでは、イベント・タイプ識別子としてゼロが割り当てられないことが保証される。
typedef enum {
JVMTI_EVENT_SINGLE_STEP = 1,
JVMTI_EVENT_BREAKPOINT = 2,
...
} jvmtiEvent;
|
jvmtiEventCallbacks | イベント用コールバック。
typedef struct {
jvmtiEventVMInit VMInit;
jvmtiEventVMDeath VMDeath;
...
} jvmtiEventCallbacks;
完全な構造については「イベント・コールバック」を参照。
たとえば、VM初期化コールバックは次のように定義される。
typedef void (JNICALL *jvmtiEventVMInit)
(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread);
コールバック関数の定義については個々のイベントを参照。
|
jniNativeInterface | JNI仕様で定義されたJNI関数テーブルJNINativeInterface の型識別子。JNI参照実装では、下線付きで定義される。
|
typedef struct JNINativeInterface_ jniNativeInterface;
|
位置
|
機能
|
宣言
|
1 | 予約済み |
void *reserved1;
|
2 | イベント通知モードの設定 |
jvmtiError (JNICALL *SetEventNotificationMode) (jvmtiEnv* env,
jvmtiEventMode mode,
jvmtiEvent event_type,
jthread event_thread,
...);
|
3 | 予約済み |
void *reserved3;
|
4 | すべてのスレッドの取得 |
jvmtiError (JNICALL *GetAllThreads) (jvmtiEnv* env,
jint* threads_count_ptr,
jthread** threads_ptr);
|
5 | スレッドの中断 |
jvmtiError (JNICALL *SuspendThread) (jvmtiEnv* env,
jthread thread);
|
6 | スレッドの再開 |
jvmtiError (JNICALL *ResumeThread) (jvmtiEnv* env,
jthread thread);
|
7 | スレッドの停止 |
jvmtiError (JNICALL *StopThread) (jvmtiEnv* env,
jthread thread,
jobject exception);
|
8 | スレッドの割り込み |
jvmtiError (JNICALL *InterruptThread) (jvmtiEnv* env,
jthread thread);
|
9 | スレッド情報の取得 |
jvmtiError (JNICALL *GetThreadInfo) (jvmtiEnv* env,
jthread thread,
jvmtiThreadInfo* info_ptr);
|
10 | 所有モニター情報の取得 |
jvmtiError (JNICALL *GetOwnedMonitorInfo) (jvmtiEnv* env,
jthread thread,
jint* owned_monitor_count_ptr,
jobject** owned_monitors_ptr);
|
11 | 現在競合しているモニターの取得 |
jvmtiError (JNICALL *GetCurrentContendedMonitor) (jvmtiEnv* env,
jthread thread,
jobject* monitor_ptr);
|
12 | エージェント・スレッドの実行 |
jvmtiError (JNICALL *RunAgentThread) (jvmtiEnv* env,
jthread thread,
jvmtiStartFunction proc,
const void* arg,
jint priority);
|
13 | トップ・レベルのスレッド・グループの取得 |
jvmtiError (JNICALL *GetTopThreadGroups) (jvmtiEnv* env,
jint* group_count_ptr,
jthreadGroup** groups_ptr);
|
14 | スレッド・グループ情報の取得 |
jvmtiError (JNICALL *GetThreadGroupInfo) (jvmtiEnv* env,
jthreadGroup group,
jvmtiThreadGroupInfo* info_ptr);
|
15 | 子スレッド・グループの取得 |
jvmtiError (JNICALL *GetThreadGroupChildren) (jvmtiEnv* env,
jthreadGroup group,
jint* thread_count_ptr,
jthread** threads_ptr,
jint* group_count_ptr,
jthreadGroup** groups_ptr);
|
16 | フレーム・カウントの取得 |
jvmtiError (JNICALL *GetFrameCount) (jvmtiEnv* env,
jthread thread,
jint* count_ptr);
|
17 | スレッド状態の取得 |
jvmtiError (JNICALL *GetThreadState) (jvmtiEnv* env,
jthread thread,
jint* thread_state_ptr);
|
18 | 現在のスレッドの取得 |
jvmtiError (JNICALL *GetCurrentThread) (jvmtiEnv* env,
jthread* thread_ptr);
|
19 | フレームの位置の取得 |
jvmtiError (JNICALL *GetFrameLocation) (jvmtiEnv* env,
jthread thread,
jint depth,
jmethodID* method_ptr,
jlocation* location_ptr);
|
20 | フレームのポップの通知 |
jvmtiError (JNICALL *NotifyFramePop) (jvmtiEnv* env,
jthread thread,
jint depth);
|
21 | 局所変数の取得 - オブジェクト型 |
jvmtiError (JNICALL *GetLocalObject) (jvmtiEnv* env,
jthread thread,
jint depth,
jint slot,
jobject* value_ptr);
|
22 | 局所変数の取得 - 整数型 |
jvmtiError (JNICALL *GetLocalInt) (jvmtiEnv* env,
jthread thread,
jint depth,
jint slot,
jint* value_ptr);
|
23 | 局所変数の取得 - 長整数型 |
jvmtiError (JNICALL *GetLocalLong) (jvmtiEnv* env,
jthread thread,
jint depth,
jint slot,
jlong* value_ptr);
|
24 | 局所変数の取得 - 浮動小数点数型 |
jvmtiError (JNICALL *GetLocalFloat) (jvmtiEnv* env,
jthread thread,
jint depth,
jint slot,
jfloat* value_ptr);
|
25 | 局所変数の取得 - 倍精度浮動小数点数型 |
jvmtiError (JNICALL *GetLocalDouble) (jvmtiEnv* env,
jthread thread,
jint depth,
jint slot,
jdouble* value_ptr);
|
26 | 局所変数の設定 - オブジェクト型 |
jvmtiError (JNICALL *SetLocalObject) (jvmtiEnv* env,
jthread thread,
jint depth,
jint slot,
jobject value);
|
27 | 局所変数の設定 - 整数型 |
jvmtiError (JNICALL *SetLocalInt) (jvmtiEnv* env,
jthread thread,
jint depth,
jint slot,
jint value);
|
28 | 局所変数の設定 - 長整数型 |
jvmtiError (JNICALL *SetLocalLong) (jvmtiEnv* env,
jthread thread,
jint depth,
jint slot,
jlong value);
|
29 | 局所変数の設定 - 浮動小数点数型 |
jvmtiError (JNICALL *SetLocalFloat) (jvmtiEnv* env,
jthread thread,
jint depth,
jint slot,
jfloat value);
|
30 | 局所変数の設定 - 倍精度浮動小数点数型 |
jvmtiError (JNICALL *SetLocalDouble) (jvmtiEnv* env,
jthread thread,
jint depth,
jint slot,
jdouble value);
|
31 | rawモニターの作成 |
jvmtiError (JNICALL *CreateRawMonitor) (jvmtiEnv* env,
const char* name,
jrawMonitorID* monitor_ptr);
|
32 | rawモニターの破棄 |
jvmtiError (JNICALL *DestroyRawMonitor) (jvmtiEnv* env,
jrawMonitorID monitor);
|
33 | rawモニターの開始 |
jvmtiError (JNICALL *RawMonitorEnter) (jvmtiEnv* env,
jrawMonitorID monitor);
|
34 | rawモニターの終了 |
jvmtiError (JNICALL *RawMonitorExit) (jvmtiEnv* env,
jrawMonitorID monitor);
|
35 | rawモニターの待機 |
jvmtiError (JNICALL *RawMonitorWait) (jvmtiEnv* env,
jrawMonitorID monitor,
jlong millis);
|
36 | rawモニターの通知 |
jvmtiError (JNICALL *RawMonitorNotify) (jvmtiEnv* env,
jrawMonitorID monitor);
|
37 | rawモニターの通知(すべて) |
jvmtiError (JNICALL *RawMonitorNotifyAll) (jvmtiEnv* env,
jrawMonitorID monitor);
|
38 | ブレークポイントの設定 |
jvmtiError (JNICALL *SetBreakpoint) (jvmtiEnv* env,
jmethodID method,
jlocation location);
|
39 | ブレークポイントの解除 |
jvmtiError (JNICALL *ClearBreakpoint) (jvmtiEnv* env,
jmethodID method,
jlocation location);
|
40 | 予約済み |
void *reserved40;
|
41 | フィールド・アクセスの監視の設定 |
jvmtiError (JNICALL *SetFieldAccessWatch) (jvmtiEnv* env,
jclass klass,
jfieldID field);
|
42 | フィールド・アクセスの監視の解除 |
jvmtiError (JNICALL *ClearFieldAccessWatch) (jvmtiEnv* env,
jclass klass,
jfieldID field);
|
43 | フィールド変更の監視の設定 |
jvmtiError (JNICALL *SetFieldModificationWatch) (jvmtiEnv* env,
jclass klass,
jfieldID field);
|
44 | フィールド変更の監視の解除 |
jvmtiError (JNICALL *ClearFieldModificationWatch) (jvmtiEnv* env,
jclass klass,
jfieldID field);
|
45 | 変更可能クラスかどうかの検査 |
jvmtiError (JNICALL *IsModifiableClass) (jvmtiEnv* env,
jclass klass,
jboolean* is_modifiable_class_ptr);
|
46 | Allocate |
jvmtiError (JNICALL *Allocate) (jvmtiEnv* env,
jlong size,
unsigned char** mem_ptr);
|
47 | Deallocate |
jvmtiError (JNICALL *Deallocate) (jvmtiEnv* env,
unsigned char* mem);
|
48 | クラスのシグニチャの取得 |
jvmtiError (JNICALL *GetClassSignature) (jvmtiEnv* env,
jclass klass,
char** signature_ptr,
char** generic_ptr);
|
49 | クラスのステータスの取得 |
jvmtiError (JNICALL *GetClassStatus) (jvmtiEnv* env,
jclass klass,
jint* status_ptr);
|
50 | ソース・ファイル名の取得 |
jvmtiError (JNICALL *GetSourceFileName) (jvmtiEnv* env,
jclass klass,
char** source_name_ptr);
|
51 | クラスの修飾子の取得 |
jvmtiError (JNICALL *GetClassModifiers) (jvmtiEnv* env,
jclass klass,
jint* modifiers_ptr);
|
52 | クラスのメソッドの取得 |
jvmtiError (JNICALL *GetClassMethods) (jvmtiEnv* env,
jclass klass,
jint* method_count_ptr,
jmethodID** methods_ptr);
|
53 | クラスのフィールドの取得 |
jvmtiError (JNICALL *GetClassFields) (jvmtiEnv* env,
jclass klass,
jint* field_count_ptr,
jfieldID** fields_ptr);
|
54 | 実装されたインタフェースの取得 |
jvmtiError (JNICALL *GetImplementedInterfaces) (jvmtiEnv* env,
jclass klass,
jint* interface_count_ptr,
jclass** interfaces_ptr);
|
55 | インタフェースかどうかの検査 |
jvmtiError (JNICALL *IsInterface) (jvmtiEnv* env,
jclass klass,
jboolean* is_interface_ptr);
|
56 | 配列クラスかどうかの検査 |
jvmtiError (JNICALL *IsArrayClass) (jvmtiEnv* env,
jclass klass,
jboolean* is_array_class_ptr);
|
57 | クラス・ローダーの取得 |
jvmtiError (JNICALL *GetClassLoader) (jvmtiEnv* env,
jclass klass,
jobject* classloader_ptr);
|
58 | オブジェクトのハッシュ・コードの取得 |
jvmtiError (JNICALL *GetObjectHashCode) (jvmtiEnv* env,
jobject object,
jint* hash_code_ptr);
|
59 | オブジェクトのモニターの利用情報を取得 |
jvmtiError (JNICALL *GetObjectMonitorUsage) (jvmtiEnv* env,
jobject object,
jvmtiMonitorUsage* info_ptr);
|
60 | フィールドの名前とシグニチャの取得 |
jvmtiError (JNICALL *GetFieldName) (jvmtiEnv* env,
jclass klass,
jfieldID field,
char** name_ptr,
char** signature_ptr,
char** generic_ptr);
|
61 | フィールドの宣言クラスの取得 |
jvmtiError (JNICALL *GetFieldDeclaringClass) (jvmtiEnv* env,
jclass klass,
jfieldID field,
jclass* declaring_class_ptr);
|
62 | フィールドの修飾子の取得 |
jvmtiError (JNICALL *GetFieldModifiers) (jvmtiEnv* env,
jclass klass,
jfieldID field,
jint* modifiers_ptr);
|
63 | 合成フィールドかどうかの検査 |
jvmtiError (JNICALL *IsFieldSynthetic) (jvmtiEnv* env,
jclass klass,
jfieldID field,
jboolean* is_synthetic_ptr);
|
64 | メソッドの名前とシグニチャの取得 |
jvmtiError (JNICALL *GetMethodName) (jvmtiEnv* env,
jmethodID method,
char** name_ptr,
char** signature_ptr,
char** generic_ptr);
|
65 | メソッドの宣言クラスの取得 |
jvmtiError (JNICALL *GetMethodDeclaringClass) (jvmtiEnv* env,
jmethodID method,
jclass* declaring_class_ptr);
|
66 | メソッドの修飾子の取得 |
jvmtiError (JNICALL *GetMethodModifiers) (jvmtiEnv* env,
jmethodID method,
jint* modifiers_ptr);
|
67 | 予約済み |
void *reserved67;
|
68 | 局所変数の取得 |
jvmtiError (JNICALL *GetMaxLocals) (jvmtiEnv* env,
jmethodID method,
jint* max_ptr);
|
69 | 引数のサイズの取得 |
jvmtiError (JNICALL *GetArgumentsSize) (jvmtiEnv* env,
jmethodID method,
jint* size_ptr);
|
70 | 行番号テーブルの取得 |
jvmtiError (JNICALL *GetLineNumberTable) (jvmtiEnv* env,
jmethodID method,
jint* entry_count_ptr,
jvmtiLineNumberEntry** table_ptr);
|
71 | メソッドの配置位置の取得 |
jvmtiError (JNICALL *GetMethodLocation) (jvmtiEnv* env,
jmethodID method,
jlocation* start_location_ptr,
jlocation* end_location_ptr);
|
72 | 局所変数テーブルの取得 |
jvmtiError (JNICALL *GetLocalVariableTable) (jvmtiEnv* env,
jmethodID method,
jint* entry_count_ptr,
jvmtiLocalVariableEntry** table_ptr);
|
73 | ネイティブ・メソッド接頭辞の設定 |
jvmtiError (JNICALL *SetNativeMethodPrefix) (jvmtiEnv* env,
const char* prefix);
|
74 | 複数のネイティブ・メソッド接頭辞の設定 |
jvmtiError (JNICALL *SetNativeMethodPrefixes) (jvmtiEnv* env,
jint prefix_count,
char** prefixes);
|
75 | バイト・コードの取得 |
jvmtiError (JNICALL *GetBytecodes) (jvmtiEnv* env,
jmethodID method,
jint* bytecode_count_ptr,
unsigned char** bytecodes_ptr);
|
76 | ネイティブ・メソッドかどうかの検査 |
jvmtiError (JNICALL *IsMethodNative) (jvmtiEnv* env,
jmethodID method,
jboolean* is_native_ptr);
|
77 | 合成メソッドかどうかの検査 |
jvmtiError (JNICALL *IsMethodSynthetic) (jvmtiEnv* env,
jmethodID method,
jboolean* is_synthetic_ptr);
|
78 | ロード済みクラスの取得 |
jvmtiError (JNICALL *GetLoadedClasses) (jvmtiEnv* env,
jint* class_count_ptr,
jclass** classes_ptr);
|
79 | クラス・ローダー・クラスの取得 |
jvmtiError (JNICALL *GetClassLoaderClasses) (jvmtiEnv* env,
jobject initiating_loader,
jint* class_count_ptr,
jclass** classes_ptr);
|
80 | フレームのポップ |
jvmtiError (JNICALL *PopFrame) (jvmtiEnv* env,
jthread thread);
|
81 | 早期復帰の強制 - オブジェクト型 |
jvmtiError (JNICALL *ForceEarlyReturnObject) (jvmtiEnv* env,
jthread thread,
jobject value);
|
82 | 早期復帰の強制 - 整数型 |
jvmtiError (JNICALL *ForceEarlyReturnInt) (jvmtiEnv* env,
jthread thread,
jint value);
|
83 | 早期復帰の強制 - 長整数型 |
jvmtiError (JNICALL *ForceEarlyReturnLong) (jvmtiEnv* env,
jthread thread,
jlong value);
|
84 | 早期復帰の強制 - 浮動小数点数型 |
jvmtiError (JNICALL *ForceEarlyReturnFloat) (jvmtiEnv* env,
jthread thread,
jfloat value);
|
85 | 早期復帰の強制 - 倍精度浮動小数点数型 |
jvmtiError (JNICALL *ForceEarlyReturnDouble) (jvmtiEnv* env,
jthread thread,
jdouble value);
|
86 | 早期復帰の強制 - void型 |
jvmtiError (JNICALL *ForceEarlyReturnVoid) (jvmtiEnv* env,
jthread thread);
|
87 | クラスの再定義 |
jvmtiError (JNICALL *RedefineClasses) (jvmtiEnv* env,
jint class_count,
const jvmtiClassDefinition* class_definitions);
|
88 | バージョン番号の取得 |
jvmtiError (JNICALL *GetVersionNumber) (jvmtiEnv* env,
jint* version_ptr);
|
89 | 権限の取得 |
jvmtiError (JNICALL *GetCapabilities) (jvmtiEnv* env,
jvmtiCapabilities* capabilities_ptr);
|
90 | ソース・デバッグ拡張機能の取得 |
jvmtiError (JNICALL *GetSourceDebugExtension) (jvmtiEnv* env,
jclass klass,
char** source_debug_extension_ptr);
|
91 | 廃棄されたメソッドかどうかの検査 |
jvmtiError (JNICALL *IsMethodObsolete) (jvmtiEnv* env,
jmethodID method,
jboolean* is_obsolete_ptr);
|
92 | スレッド・リストの中断 |
jvmtiError (JNICALL *SuspendThreadList) (jvmtiEnv* env,
jint request_count,
const jthread* request_list,
jvmtiError* results);
|
93 | スレッド・リストの再開 |
jvmtiError (JNICALL *ResumeThreadList) (jvmtiEnv* env,
jint request_count,
const jthread* request_list,
jvmtiError* results);
|
94 | 予約済み |
void *reserved94;
|
95 | 予約済み |
void *reserved95;
|
96 | 予約済み |
void *reserved96;
|
97 | 予約済み |
void *reserved97;
|
98 | 予約済み |
void *reserved98;
|
99 | 予約済み |
void *reserved99;
|
100 | すべてのスタック・トレースの取得 |
jvmtiError (JNICALL *GetAllStackTraces) (jvmtiEnv* env,
jint max_frame_count,
jvmtiStackInfo** stack_info_ptr,
jint* thread_count_ptr);
|
101 | スレッド・リストのスタック・トレースの取得 |
jvmtiError (JNICALL *GetThreadListStackTraces) (jvmtiEnv* env,
jint thread_count,
const jthread* thread_list,
jint max_frame_count,
jvmtiStackInfo** stack_info_ptr);
|
102 | スレッド・ローカルな記憶領域の取得 |
jvmtiError (JNICALL *GetThreadLocalStorage) (jvmtiEnv* env,
jthread thread,
void** data_ptr);
|
103 | スレッド・ローカルな記憶領域の設定 |
jvmtiError (JNICALL *SetThreadLocalStorage) (jvmtiEnv* env,
jthread thread,
const void* data);
|
104 | スタック・トレースの取得 |
jvmtiError (JNICALL *GetStackTrace) (jvmtiEnv* env,
jthread thread,
jint start_depth,
jint max_frame_count,
jvmtiFrameInfo* frame_buffer,
jint* count_ptr);
|
105 | 予約済み |
void *reserved105;
|
106 | タグの取得 |
jvmtiError (JNICALL *GetTag) (jvmtiEnv* env,
jobject object,
jlong* tag_ptr);
|
107 | タグの設定 |
jvmtiError (JNICALL *SetTag) (jvmtiEnv* env,
jobject object,
jlong tag);
|
108 | ガベージ・コレクションの強制 |
jvmtiError (JNICALL *ForceGarbageCollection) (jvmtiEnv* env);
|
109 | オブジェクトから到達可能なオブジェクトの反復 |
jvmtiError (JNICALL *IterateOverObjectsReachableFromObject) (jvmtiEnv* env,
jobject object,
jvmtiObjectReferenceCallback object_reference_callback,
const void* user_data);
|
110 | 到達可能なオブジェクトの反復 |
jvmtiError (JNICALL *IterateOverReachableObjects) (jvmtiEnv* env,
jvmtiHeapRootCallback heap_root_callback,
jvmtiStackReferenceCallback stack_ref_callback,
jvmtiObjectReferenceCallback object_ref_callback,
const void* user_data);
|
111 | ヒープの反復 |
jvmtiError (JNICALL *IterateOverHeap) (jvmtiEnv* env,
jvmtiHeapObjectFilter object_filter,
jvmtiHeapObjectCallback heap_object_callback,
const void* user_data);
|
112 | クラスのインスタンスの反復 |
jvmtiError (JNICALL *IterateOverInstancesOfClass) (jvmtiEnv* env,
jclass klass,
jvmtiHeapObjectFilter object_filter,
jvmtiHeapObjectCallback heap_object_callback,
const void* user_data);
|
113 | 予約済み |
void *reserved113;
|
114 | タグを使ったオブジェクトの取得 |
jvmtiError (JNICALL *GetObjectsWithTags) (jvmtiEnv* env,
jint tag_count,
const jlong* tags,
jint* count_ptr,
jobject** object_result_ptr,
jlong** tag_result_ptr);
|
115 | 参照の追跡 |
jvmtiError (JNICALL *FollowReferences) (jvmtiEnv* env,
jint heap_filter,
jclass klass,
jobject initial_object,
const jvmtiHeapCallbacks* callbacks,
const void* user_data);
|
116 | ヒープ内での反復 |
jvmtiError (JNICALL *IterateThroughHeap) (jvmtiEnv* env,
jint heap_filter,
jclass klass,
const jvmtiHeapCallbacks* callbacks,
const void* user_data);
|
117 | 予約済み |
void *reserved117;
|
118 | 予約済み |
void *reserved118;
|
119 | 予約済み |
void *reserved119;
|
120 | JNI関数テーブルの設定 |
jvmtiError (JNICALL *SetJNIFunctionTable) (jvmtiEnv* env,
const jniNativeInterface* function_table);
|
121 | JNI関数テーブルの取得 |
jvmtiError (JNICALL *GetJNIFunctionTable) (jvmtiEnv* env,
jniNativeInterface** function_table);
|
122 | イベント・コールバックの設定 |
jvmtiError (JNICALL *SetEventCallbacks) (jvmtiEnv* env,
const jvmtiEventCallbacks* callbacks,
jint size_of_callbacks);
|
123 | イベントの生成 |
jvmtiError (JNICALL *GenerateEvents) (jvmtiEnv* env,
jvmtiEvent event_type);
|
124 | 拡張関数の取得 |
jvmtiError (JNICALL *GetExtensionFunctions) (jvmtiEnv* env,
jint* extension_count_ptr,
jvmtiExtensionFunctionInfo** extensions);
|
125 | 拡張イベントの取得 |
jvmtiError (JNICALL *GetExtensionEvents) (jvmtiEnv* env,
jint* extension_count_ptr,
jvmtiExtensionEventInfo** extensions);
|
126 | 拡張イベント・コールバックの設定 |
jvmtiError (JNICALL *SetExtensionEventCallback) (jvmtiEnv* env,
jint extension_event_index,
jvmtiExtensionEvent callback);
|
127 | 環境の破棄 |
jvmtiError (JNICALL *DisposeEnvironment) (jvmtiEnv* env);
|
128 | エラー名の取得 |
jvmtiError (JNICALL *GetErrorName) (jvmtiEnv* env,
jvmtiError error,
char** name_ptr);
|
129 | JLocation形式の取得 |
jvmtiError (JNICALL *GetJLocationFormat) (jvmtiEnv* env,
jvmtiJlocationFormat* format_ptr);
|
130 | システム・プロパティの取得 |
jvmtiError (JNICALL *GetSystemProperties) (jvmtiEnv* env,
jint* count_ptr,
char*** property_ptr);
|
131 | システム・プロパティの取得 |
jvmtiError (JNICALL *GetSystemProperty) (jvmtiEnv* env,
const char* property,
char** value_ptr);
|
132 | システム・プロパティの設定 |
jvmtiError (JNICALL *SetSystemProperty) (jvmtiEnv* env,
const char* property,
const char* value_ptr);
|
133 | 段階の取得 |
jvmtiError (JNICALL *GetPhase) (jvmtiEnv* env,
jvmtiPhase* phase_ptr);
|
134 | 現在のスレッドのCPUタイマー情報を取得 |
jvmtiError (JNICALL *GetCurrentThreadCpuTimerInfo) (jvmtiEnv* env,
jvmtiTimerInfo* info_ptr);
|
135 | 現在のスレッドのCPU時間を取得 |
jvmtiError (JNICALL *GetCurrentThreadCpuTime) (jvmtiEnv* env,
jlong* nanos_ptr);
|
136 | スレッドのCPUタイマー情報を取得 |
jvmtiError (JNICALL *GetThreadCpuTimerInfo) (jvmtiEnv* env,
jvmtiTimerInfo* info_ptr);
|
137 | スレッドのCPU時間を取得 |
jvmtiError (JNICALL *GetThreadCpuTime) (jvmtiEnv* env,
jthread thread,
jlong* nanos_ptr);
|
138 | タイマー情報の取得 |
jvmtiError (JNICALL *GetTimerInfo) (jvmtiEnv* env,
jvmtiTimerInfo* info_ptr);
|
139 | 時間の取得 |
jvmtiError (JNICALL *GetTime) (jvmtiEnv* env,
jlong* nanos_ptr);
|
140 | 潜在的な権限の取得 |
jvmtiError (JNICALL *GetPotentialCapabilities) (jvmtiEnv* env,
jvmtiCapabilities* capabilities_ptr);
|
141 | 予約済み |
void *reserved141;
|
142 | 権限の追加 |
jvmtiError (JNICALL *AddCapabilities) (jvmtiEnv* env,
const jvmtiCapabilities* capabilities_ptr);
|
143 | 権限の放棄 |
jvmtiError (JNICALL *RelinquishCapabilities) (jvmtiEnv* env,
const jvmtiCapabilities* capabilities_ptr);
|
144 | 使用可能なプロセッサの取得 |
jvmtiError (JNICALL *GetAvailableProcessors) (jvmtiEnv* env,
jint* processor_count_ptr);
|
145 | クラス・バージョン番号の取得 |
jvmtiError (JNICALL *GetClassVersionNumbers) (jvmtiEnv* env,
jclass klass,
jint* minor_version_ptr,
jint* major_version_ptr);
|
146 | 定数プールの取得 |
jvmtiError (JNICALL *GetConstantPool) (jvmtiEnv* env,
jclass klass,
jint* constant_pool_count_ptr,
jint* constant_pool_byte_count_ptr,
unsigned char** constant_pool_bytes_ptr);
|
147 | 環境ローカル記憶領域の取得 |
jvmtiError (JNICALL *GetEnvironmentLocalStorage) (jvmtiEnv* env,
void** data_ptr);
|
148 | 環境ローカル記憶領域の設定 |
jvmtiError (JNICALL *SetEnvironmentLocalStorage) (jvmtiEnv* env,
const void* data);
|
149 | ブートストラップ・クラス・ローダー検索の追加 |
jvmtiError (JNICALL *AddToBootstrapClassLoaderSearch) (jvmtiEnv* env,
const char* segment);
|
150 | 冗長フラグの設定 |
jvmtiError (JNICALL *SetVerboseFlag) (jvmtiEnv* env,
jvmtiVerboseFlag flag,
jboolean value);
|
151 | システム・クラス・ローダー検索の追加 |
jvmtiError (JNICALL *AddToSystemClassLoaderSearch) (jvmtiEnv* env,
const char* segment);
|
152 | クラスの再変換 |
jvmtiError (JNICALL *RetransformClasses) (jvmtiEnv* env,
jint class_count,
const jclass* classes);
|
153 | 所有モニターのスタックの深さ情報の取得 |
jvmtiError (JNICALL *GetOwnedMonitorStackDepthInfo) (jvmtiEnv* env,
jthread thread,
jint* monitor_info_count_ptr,
jvmtiMonitorStackDepthInfo** monitor_info_ptr);
|
154 | オブジェクト・サイズの取得 |
jvmtiError (JNICALL *GetObjectSize) (jvmtiEnv* env,
jobject object,
jlong* size_ptr);
|
155 | 局所インスタンスの取得 |
jvmtiError (JNICALL *GetLocalInstance) (jvmtiEnv* env,
jthread thread,
jint depth,
jobject* value_ptr);
|
イベント
イベントの処理
エージェントは、アプリケーション・プログラム内で発生する多くのイベントについての通知を受けることができます。
イベントを処理するには、SetEventCallbacks
を使ってコールバック関数のセットを指定します。イベントごとに、対応するコールバック関数が呼び出されます。コールバック関数の引数は、イベントに関する追加情報を提供します。
コールバック関数は通常、アプリケーション・スレッド内から呼び出されます。JVM TI実装がイベントをキューに入れることは、決してありません。これは、イベントのコールバック関数を注意深く記述する必要があることを意味しています。このあと、一般的なガイドラインを説明します。さらに詳しい提案については、個々のイベントの説明を参照してください。
- イベント・コールバック関数の実行中にスローされた例外は、現在のアプリケーション・スレッド内で現在保留中の例外を上書きできてしまいます。したがって、例外を生成する可能性のあるJNI呼出しをイベント・コールバック関数から実行する場合は、保留中の例外を保存するように気を付けなければなりません。
- イベント・コールバック関数は、再入可能でなければなりません。JVM TI実装は、イベントをキューに入れません。エージェントが複数のイベントを一度に1つずつ処理する必要がある場合は、イベント・コールバック関数の内部でrawモニターを使うと、イベントの処理を直列化できます。
- JNIのFindClass関数を実行してクラスをロードするイベント・コールバック関数では、FindClassは現在のネイティブ・メソッドに関連付けられたクラス・ローダーを見つける、という点に注意する必要があります。クラスのロードの目的とする場合、コールバックのパラメータとしてJNI環境を含むイベント・コールバックは、それがネイティブ呼出しであるかのように扱われます(そのネイティブ・メソッドは、イベント・スレッドの現在のフレームのクラス内に存在する)。
JVM TIイベントの中には、JNI参照を使ってオブジェクトを識別するものがあります。JVM TIイベント内のすべての参照は、JNIローカル参照で、イベント・コールバック関数から復帰すると無効になります。記述されていない場合、イベント・コールバック内で送信されたポインタによって参照されるメモリーは、イベント・コールバックの終了後は参照できません。
特に明記されていないかぎり、イベントの配信は、そのイベントが発生したスレッド上で行われます。イベントは発生と同時に送信されます。各イベントの仕様には、そのイベントの送信が可能な段階のセットが含まれています。イベントをトリガーするアクティビティが別の段階で発生しても、イベントは送信されません。
イベントを生成するスレッドの実行ステータスが変更されることはありません(たとえば、イベントによってスレッドが中断されることはない)。エージェントがイベント発生時の中断を必要とする場合、SuspendThread
でスレッドを明示的に中断するのは、エージェントの責任となります。
複数の環境で有効になっているイベントは、これらの環境が作成された順に、各エージェントに送信されます。
イベントの有効化
すべてのイベントは、初期段階では無効になっています。イベントを受信するには、次のようにします。
同じ位置で発生する複数のイベント
多くの状況で、1つのスレッド内の同じ位置で複数のイベントが発生する可能性があります。そのような状況では、このセクションで説明する順序で、イベント・コールバックによりすべてのイベントがレポートされます。
現在位置がメソッドのエントリ・ポイントである場合は、同一スレッド内の現在位置で発生したほかのすべてのイベントより前に、MethodEntry
イベントがレポートされます。
現在位置で例外のキャッチが検出された場合(catch節の先頭の場合か、未処理の例外を解除したネイティブ・メソッドが復帰した位置の場合)は、同一スレッド内の現在位置で発生したほかのすべてのイベントより前に、exceptionCatch
イベントがレポートされます。
singleStep
イベントまたはbreakpoint
イベントが現在位置でトリガーされる場合、そのイベントは、現在位置のコードが実行される直前に発生するものと定義されています。これらのイベントは、同一スレッド内の現在位置にあるコードの実行によりトリガーされるどのイベント(特に、exception
、fieldAccess
、およびfieldModification
)よりも前にレポートされます。ステップ・イベントとブレークポイント・イベントの両方が同一のスレッドおよび場所でトリガーされた場合は、ステップ・イベントがブレークポイント・イベントより前にレポートされます。
現在位置がメソッドの終了ポイント(つまり、呼出し側に復帰する前の最後の位置)である場合、MethodExit
イベントおよびFramePop
イベント(要求されている場合)は、同一スレッド内の現在位置で発生するほかのすべてのイベントのあとにレポートされます。これら2つのイベントについては、レポートされる順序は特に指定されていません。
あるイベントをエージェントが処理している最中に、同じスレッド内の同じ位置で別の(共通位置)イベントがトリガーされる可能性があります。x型のイベントの処理中にそのようなy型のイベントがトリガーされ、かつ上で規定した順序付けに基づいてxがyよりも先である場合、現在のスレッドと位置に対して共通位置イベントyが報告されます。xがyよりも先でない場合、yは現在のスレッドと位置に対して報告されません。たとえば、SingleStep
の処理中に現在位置でブレークポイントが設定された場合、そのブレークポイントは、スレッドが現在位置を離れる前に報告されます。
以下のイベントは、ほかのイベントと同じ位置で発生したと見なされることがありません。
イベント・コールバック
以下のイベント・コールバック構造体では、イベントのハンドラ関数を指定できます。これは、SetEventCallbacks
関数で設定されます。
typedef struct {
jvmtiEventVMInit VMInit;
jvmtiEventVMDeath VMDeath;
jvmtiEventThreadStart ThreadStart;
jvmtiEventThreadEnd ThreadEnd;
jvmtiEventClassFileLoadHook ClassFileLoadHook;
jvmtiEventClassLoad ClassLoad;
jvmtiEventClassPrepare ClassPrepare;
jvmtiEventVMStart VMStart;
jvmtiEventException Exception;
jvmtiEventExceptionCatch ExceptionCatch;
jvmtiEventSingleStep SingleStep;
jvmtiEventFramePop FramePop;
jvmtiEventBreakpoint Breakpoint;
jvmtiEventFieldAccess FieldAccess;
jvmtiEventFieldModification FieldModification;
jvmtiEventMethodEntry MethodEntry;
jvmtiEventMethodExit MethodExit;
jvmtiEventNativeMethodBind NativeMethodBind;
jvmtiEventCompiledMethodLoad CompiledMethodLoad;
jvmtiEventCompiledMethodUnload CompiledMethodUnload;
jvmtiEventDynamicCodeGenerated DynamicCodeGenerated;
jvmtiEventDataDumpRequest DataDumpRequest;
jvmtiEventReserved reserved72;
jvmtiEventMonitorWait MonitorWait;
jvmtiEventMonitorWaited MonitorWaited;
jvmtiEventMonitorContendedEnter MonitorContendedEnter;
jvmtiEventMonitorContendedEntered MonitorContendedEntered;
jvmtiEventReserved reserved77;
jvmtiEventReserved reserved78;
jvmtiEventReserved reserved79;
jvmtiEventResourceExhausted ResourceExhausted;
jvmtiEventGarbageCollectionStart GarbageCollectionStart;
jvmtiEventGarbageCollectionFinish GarbageCollectionFinish;
jvmtiEventObjectFree ObjectFree;
jvmtiEventVMObjectAlloc VMObjectAlloc;
} jvmtiEventCallbacks;
イベントの索引
ステップ実行
void JNICALL
SingleStep(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jmethodID method,
jlocation location)
ステップ実行イベントを利用すると、エージェントは、VMで可能な最小の単位でスレッドの実行を追跡できます。ステップ実行イベントは、スレッドが新しい位置に達するたびに生成されます。通常、ステップ実行イベントは、Java(tm)仮想マシン仕様に定義されているように、1つのVM命令が完了したことを示します。ただし、位置の定義が異なる実装もあります。いずれにしても、method
およびlocation
パラメータによって現在の位置を一意に識別できるため、この情報があればソース・ファイルと行番号へのマッピングが可能です。
ネイティブ・メソッド内からは、ステップ実行イベントは生成されません。
ブレークポイント
void JNICALL
Breakpoint(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jmethodID method,
jlocation location)
ブレークポイント・イベントは、SetBreakpoint
を使ってブレークポイントとして指定された位置にスレッドが達した時点で生成されます。method
およびlocation
パラメータは、現在の位置を一意に識別し、ソース・ファイルと行番号(その情報が入手できる場合)にマッピングできます。
フィールド・アクセス
void JNICALL
FieldAccess(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jmethodID method,
jlocation location,
jclass field_klass,
jobject object,
jfieldID field)
フィールド・アクセス・イベントは、SetFieldAccessWatch
を使ってウォッチポイントとして指定されたフィールドにスレッドがアクセスした時点で生成されます。method
およびlocation
パラメータは、現在の位置を一意に識別し、ソース・ファイルと行番号(その情報が入手できる場合)にマッピングできます。
名前
|
型
|
説明
|
jni_env | JNIEnv * |
イベントの現在のスレッドのJNI環境
|
thread | jthread |
フィールドにアクセスするスレッド
|
method | jmethodID |
アクセスが発生しているメソッド
|
location | jlocation |
アクセスが発生している位置
|
field_klass | jclass |
アクセスされるフィールドのクラス
|
object | jobject |
フィールドがインスタンス・フィールドの場合はアクセスされているフィールドを持つオブジェクト、それ以外の場合はNULL
|
field | jfieldID |
アクセスされているフィールド
|
フィールドの変更
void JNICALL
FieldModification(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jmethodID method,
jlocation location,
jclass field_klass,
jobject object,
jfieldID field,
char signature_type,
jvalue new_value)
フィールドの変更イベントは、SetFieldModificationWatch
を使ってウォッチポイントとして指定されたフィールドをスレッドが変更した時点で生成されます。method
およびlocation
パラメータは、現在の位置を一意に識別し、ソース・ファイルと行番号(その情報が入手できる場合)にマッピングできます。
名前
|
型
|
説明
|
jni_env | JNIEnv * |
イベントの現在のスレッドのJNI環境
|
thread | jthread |
フィールドを変更するスレッド
|
method | jmethodID |
変更が発生しているメソッド
|
location | jlocation |
変更が発生している位置
|
field_klass | jclass |
変更されているフィールドのクラス
|
object | jobject |
フィールドがインスタンス・フィールドの場合は変更されているフィールドを持つオブジェクト、それ以外の場合はNULL
|
field | jfieldID |
変更されているフィールド
|
signature_type | char |
新しい値のシグニチャの型
|
new_value | jvalue |
新しい値
|
フレームのポップ
void JNICALL
FramePop(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jmethodID method,
jboolean was_popped_by_exception)
フレーム・ポップ・イベントは、NotifyFramePop
の呼出しで指定された単一のフレーム内の単一のメソッドから出る時点で生成されます。これは、戻り命令の実行または呼出し側への例外のスローによって終了された場合、trueとなります(was_popped_by_exception
を参照)。ただし、PopFrame
関数によるフレームのポップはレポートされません。
GetFrameLocation
によりレポートされる位置は、復帰しようとしているメソッド内の復帰直前の実行可能位置を識別します。
名前
|
型
|
説明
|
jni_env | JNIEnv * |
イベントの現在のスレッドのJNI環境
|
thread | jthread |
フレームをポップするスレッド
|
method | jmethodID |
ポップされるメソッド
|
was_popped_by_exception | jboolean |
フレームが例外のスローによってポップされた場合はtrue。メソッドが戻り命令によって終了した場合はfalse。
|
メソッド・エントリ
void JNICALL
MethodEntry(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jmethodID method)
メソッド・エントリ・イベントは、Javaプログラミング言語メソッド(ネイティブ・メソッドを含む)に入る時点で生成されます。
GetFrameLocation
によりレポートされる位置は、メソッド内の初期実行可能位置を識別します。
多くのプラットフォームでは、メソッド・エントリ・イベントまたはメソッド終了イベントを有効にすると、パフォーマンスが大幅に低下します。したがって、プロ・ファイリングなど、パフォーマンスを重視する処理での使用はお薦めしません。これらの場合には、バイトコード・インストゥルメンテーションを使用すべきです。
メソッド終了
void JNICALL
MethodExit(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jmethodID method,
jboolean was_popped_by_exception,
jvalue return_value)
メソッド終了イベントは、Javaプログラミング言語メソッドおよびネイティブ・メソッドから終了する時点で生成されます。これは、戻り命令の実行または呼出し側への例外のスローによって終了された場合、trueとなります(was_popped_by_exception
を参照)。
method
フィールドは、入るメソッドまたは出るメソッドを一意に識別します。frame
フィールドは、メソッドのスタック・フレームへのアクセスを提供します。
GetFrameLocation
によりレポートされる位置は、復帰しようとしているメソッド内の復帰直前の実行可能位置を識別します。
多くのプラットフォームでは、メソッド・エントリ・イベントまたはメソッド終了イベントを有効にすると、パフォーマンスが大幅に低下します。したがって、プロ・ファイリングなど、パフォーマンスを重視する処理での使用はお薦めしません。これらの場合には、バイトコード・インストゥルメンテーションを使用すべきです。
ネイティブ・メソッドのバインド
void JNICALL
NativeMethodBind(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jmethodID method,
void* address,
void** new_address_ptr)
ネイティブ・メソッド・バインド・イベントは、VMがJavaプログラミング言語のネイティブ・メソッドを、そのネイティブ・メソッドを実装する関数のアドレスにバインドした時点で送信されます。これは、ネイティブ・メソッドの初回呼出し時に発生しますが、JNI関数RegisterNatives
の呼出し時にも発生します。このイベントを使えば、エージェントが指定するプロキシ関数にバインドをリダイレクトできます。このイベントは、ネイティブ・メソッドがバインド解除された場合には送信されません。通常、このプロキシ関数は特定のメソッドに固有であるか、あるいは一般的な場合に対応できるように自動生成されたアセンブリ・コードでなければいけません。インストゥルメンテーション・コードが実行された後、通常は元のバインディング・アドレスにある関数が呼び出されるからです。元のバインディングを復元したり、リダイレクションを変更したりするには、JNI関数RegisterNatives
を使用します。一部のイベントは初期段階で送信可能です。この時点ではJNIや大部分のJVM TIは使用不可能ですが、メソッドやアドレスを後で使用するために保存しておくことはできます。
名前
|
型
|
説明
|
jni_env | JNIEnv * |
イベントの現在のスレッドのJNI環境は、初期段階中に送信されるとNULL になる。
|
thread | jthread |
バインドを要求するスレッド
|
method | jmethodID |
バインドされるネイティブ・メソッド
|
address | void* |
VMのバインド先のアドレス(ネイティブ・メソッドの実装アドレス)
|
new_address_ptr | void** |
参照アドレスが変更された場合(つまり、*new_address_ptr が設定された場合)、代わりに、提供されたアドレスへのバインドが行われる。
|
例外
void JNICALL
Exception(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jmethodID method,
jlocation location,
jobject exception,
jmethodID catch_method,
jlocation catch_location)
例外イベントは、Javaプログラミング言語メソッド内で例外が初めて検出されるたびに生成されます。ここで、「例外」は任意のjava.lang.Throwable
を意味します。例外は、Javaプログラミング言語メソッド、ネイティブ・メソッドのいずれかによってスローされる可能性がありますが、ネイティブ・メソッドの場合には、その例外がJavaプログラミング言語メソッド内で初めて認識されるまで、イベントは生成されません。ネイティブ・メソッド内で例外が設定された後クリアされた場合(したがって、例外が一度もJavaプログラミング言語コードから可視状態にならなかった場合)、例外イベントは生成されません。
method
およびlocation
パラメータは、現在の位置(例外が検出された位置)を一意に識別し、ソース・ファイルと行番号(その情報が入手できる場合)にマッピングできます。exception
フィールドは、スローされた例外オブジェクトを識別します。catch_method
とcatch_location
は、スローされた例外を処理するcatch節が存在する場合に、その位置を識別します。そのようなcatch節が存在しない場合、各フィールドは0に設定されます。スレッドがこのcatch節に到達するという保証はありません。呼出しスタック上で、スロー位置とcatch節の間にネイティブ・メソッドが存在していれば、それらのネイティブ・メソッドのいずれかによって例外がリセットされる可能性があります。同様に、非キャッチとして報告された例外(catch_klass
などが0に設定された例外)は、実際にはネイティブ・メソッドによってキャッチされる可能性があります。エージェントからこれらの発生をチェックするには、ExceptionCatch
イベントを監視します。finally節は、キャッチ/再スローとして実装される点に注意してください。したがって、それらはキャッチ位置で報告されます。
例外キャッチ
void JNICALL
ExceptionCatch(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jmethodID method,
jlocation location,
jobject exception)
例外キャッチ・イベントは、スローされた例外がキャッチされた時点で生成されます。ここで、「例外」は任意のjava.lang.Throwable
を意味します。例外がJavaプログラミング言語メソッド内でキャッチされた場合は、catch節に到達した時点でこのイベントが生成されます。例外がネイティブ・メソッド内でキャッチされた場合は、Javaプログラミング言語メソッドに制御が戻った直後にこのイベントが生成されます。例外キャッチ・イベントは、Javaプログラミング言語メソッド内でスローが検出された例外に対して生成されます。finally節は、キャッチ/再スローとして実装される点に注意してください。このため、これらは例外キャッチ・イベントを生成します。
method
およびlocation
パラメータは、現在の位置を一意に識別し、ソース・ファイルと行番号(その情報が入手できる場合)にマッピングできます。Javaプログラミング言語メソッド内でキャッチされた例外の場合は、exception
オブジェクトが例外オブジェクトを識別します。ネイティブ・メソッド内でキャッチされた例外は、例外のキャッチがレポートされた時点で入手可能とはかぎらないので、exception
フィールドはNULL
に設定されます。
スレッドの開始
void JNICALL
ThreadStart(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread)
スレッド開始イベントは、新しいスレッドによって、スレッドの初期メソッドが実行される前に、生成されます。
スレッド開始イベントが生成される前に、GetAllThreads
によって返される配列に、そのスレッドが含まれている可能性があります。また、スレッド開始イベントの前に、その他のイベントがスレッド上に生成される可能性があります。
イベントは新しく開始されたthread
に送信されます。
名前
|
型
|
説明
|
jni_env | JNIEnv * |
イベントの現在のスレッドのJNI環境。
|
thread | jthread |
開始するスレッド
|
スレッドの終了
void JNICALL
ThreadEnd(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread)
スレッド終了イベントは、停止しようとしているスレッドによって、スレッドの初期メソッドの実行完了後に、生成されます。
スレッド終了イベントが生成されたあと、GetAllThreads
によって返される配列に、そのスレッドが含まれている可能性があります。スレッド終了イベントのあと、スレッド上にイベントは生成されません。
イベントは終了するthread
に送信されます。
名前
|
型
|
説明
|
jni_env | JNIEnv * |
イベントの現在のスレッドのJNI環境。
|
thread | jthread |
終了するスレッド
|
クラスのロード
void JNICALL
ClassLoad(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jclass klass)
クラス・ロード・イベントは、クラスが最初にロードされた時点で生成されます。特定のスレッドによりクラス・ロード・イベントが生成される順序は、そのスレッド内でクラスがロードされる順序と一致することが保証されています。配列クラスの作成では、クラス・ロード・イベントは生成されません。プリミティブ・クラス(java.lang.Integer.TYPEなど)の作成では、クラス・ロード・イベントは生成されません。
このイベントは、クラスのロードの早い段階で送信されます。このため、クラスは慎重に使用する必要があります。たとえば、メソッドやフィールドがまだロードされていないため、メソッド、フィールド、サブクラスなどへの照会で、正しい結果が得られません。Java言語仕様のクラスとインタフェースのロードを参照してください。ほとんどの場合、ClassPrepare
の方が有効です。
クラスの準備
void JNICALL
ClassPrepare(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jclass klass)
クラス準備イベントは、クラスの準備が完了した時点で生成されます。この時点では、クラスのフィールド、メソッド、および実装されたインタフェースが利用可能ですが、クラスのコードはまだ何も実行されていません。配列クラスは、フィールドやメソッドを持つことがないため、配列クラスについてクラス準備イベントが生成されることはありません。プリミティブ・クラス(たとえば、java.lang.Integer.TYPE
)についても、クラス準備イベントは生成されません。
名前
|
型
|
説明
|
jni_env | JNIEnv * |
イベントの現在のスレッドのJNI環境
|
thread | jthread |
クラス準備イベントを生成するスレッド
|
klass | jclass |
準備されるクラス
|
クラス・ファイル・ロードフック
void JNICALL
ClassFileLoadHook(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jclass class_being_redefined,
jobject loader,
const char* name,
jobject protection_domain,
jint class_data_len,
const unsigned char* class_data,
jint* new_class_data_len,
unsigned char** new_class_data)
このイベントは、VMがクラス・ファイル・データを取得したとき、そのクラスのメモリー内部表現を構築する前の時点で送信されます。また、このイベントは、任意のJVM TI環境内から呼び出されたRetransformClasses
関数またはRedefineClasses
関数によってクラスが変更されようとしているときにも送信されます。エージェントは、VMによって送信された既存のクラス・ファイル・データを実装して、プロ・ファイリング\/デバッグ・フックを含めることができます。使用方法については、バイト・コード・インストゥルメンテーションの説明を参照してください。
このイベントは、VMの初期化前(初期段階)に送信される可能性があります。この期間中、VMリソースは作成すべきではありません。この関数と互換性のないクラス(例: ROM化されたクラス)が存在しますが、それらのクラスではこのイベントは生成されません。
エージェントは、メモリー割当て関数Allocate
を使用して、修正したクラス・ファイル・データのバッファ用の領域を割り当てる必要があります。新しいクラス・ファイル・データのバッファを解放する処理は、VMにより、Deallocate
を使用して実行されるからです。Allocate
は初期段階で使用できます。
エージェントは、クラス・ファイルを変更する場合、新しく実装されたクラス・ファイル・データ・バッファをポイントするようにnew_class_data
を設定し、この呼び出しから戻る前に、new_class_data_len
にそのバッファの長さを設定する必要があります。変更が不要な場合、エージェントはnew_class_data
を設定しません。複数のエージェントがこのイベントを有効にしている場合、結果はチェーンになります。つまり、new_class_data
が設定されている場合は、これが次のエージェントのclass_data
になります。
このイベントが各環境に送信される順番は、ほかのイベントの場合とは異なります。このイベントは次の順番で環境に送信されます。
このイベントがRetransformClasses
によって起動された場合、再変換可能な環境だけにこのイベントが送信されます。
名前
|
型
|
説明
|
jni_env | JNIEnv * |
イベントの現在のスレッドのJNI環境。初期段階中に送信された場合はNULL になる。
|
class_being_redefined | jclass |
再定義または再変換されるクラス。クラスのロードによって送信された場合はNULL 。
|
loader | jobject |
クラスをロードするクラス・ローダー。ブートストラップ・クラス・ローダーの場合はNULL 。
|
name | const char* |
ロード対象クラスの名前。VM内部修飾名(「java/util/List」など)。modified UTF-8文字列としてエンコードされる。注: クラスの定義時にNULL 名が使用されたか名前が指定されなかった場合、name はNULL になる。
|
protection_domain | jobject |
クラスのProtectionDomain 。
|
class_data_len | jint |
現在のクラス・ファイル・データのバッファの長さ。
|
class_data | const unsigned char* |
現在のクラス・ファイル・データのバッファのポインタ。
|
new_class_data_len | jint* |
新しいクラス・ファイル・データのバッファの長さのポインタ。
|
new_class_data | unsigned char** |
実装済みクラス・ファイル・データのバッファのポインタへのポインタ。
|
VM開始イベント
void JNICALL
VMStart(jvmtiEnv *jvmti_env,
JNIEnv* jni_env)
VM初期化イベントはVMの開始を示します。この時点で、JNIはライブ状態になっていますが、VMはまだ完全に初期化されていません。このイベントが生成されたら、エージェントは任意のJNI関数を自由に呼び出せます。このイベントは開始段階の始まりを示します。開始段階で許可されたJVM TI関数を呼び出せます。
VMの起動に失敗した場合、このイベントは送信されません。
名前
|
型
|
説明
|
jni_env | JNIEnv * |
イベントの現在のスレッドのJNI環境。
|
VM初期化イベント
void JNICALL
VMInit(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread)
VM初期化イベントはVM初期化の完了を示します。このイベントが生成されたら、エージェントは任意のJNI関数またはJVM TI関数を自由に呼び出せます。VM初期化イベントと同時かそれより先に発生するイベントが存在する可能性がありますが、先行イベントが存在する場合、その処理は慎重に行うべきです。VMの初期化が完了していないからです。メイン・アプリケーション・スレッドのスレッド開始イベントは、VM初期化イベントのハンドラが復帰するまで発生しないことが保証されています。
VMの起動に失敗した場合、このイベントは送信されません。
名前
|
型
|
説明
|
jni_env | JNIEnv * |
イベントの現在のスレッドのJNI環境。
|
thread | jthread |
初期スレッド
|
VM終了イベント
void JNICALL
VMDeath(jvmtiEnv *jvmti_env,
JNIEnv* jni_env)
VM終了イベントは、VMの終了をエージェントに通知します。VMDeathイベントのあとは、イベントは発生しません。
VMの起動に失敗した場合、このイベントは送信されません。こうした場合、Agent_OnUnloadは呼び出される点に注意してください。
名前
|
型
|
説明
|
jni_env | JNIEnv * |
イベントの現在のスレッドのJNI環境
|
コンパイル済みメソッドのロード
typedef struct {
const void* start_address;
jlocation location;
} jvmtiAddrLocationMap;
void JNICALL
CompiledMethodLoad(jvmtiEnv *jvmti_env,
jmethodID method,
jint code_size,
const void* code_addr,
jint map_length,
const jvmtiAddrLocationMap* map,
const void* compile_info)
メソッドがVMによってコンパイルされ、メモリー内にロードされる時点で送信されます。アンロードされた場合、CompiledMethodUnload
イベントが送信されます。移動した場合、新しいCompiledMethodLoad
イベントに続いて、CompiledMethodUnload
イベントが送信されます。単一のメソッドが複数の形式でコンパイルされることがあり、このイベントがその形式ごとに送信される点に注意してください。また、複数のメソッドが単一のアドレス範囲にインラインされることがあり、このイベントが各メソッドごとに送信される点にも注意してください。
これらのイベントは、最初の発生のあと、GenerateEvents
によって送信できます。
名前
|
型
|
説明
|
method | jmethodID |
コンパイルおよびロードされているメソッド
|
code_size | jint |
コンパイルされたコードのサイズ
|
code_addr | const void* |
コンパイルされたメソッド・コードがロードされるアドレス
|
map_length | jint |
アドレス・マップ内のjvmtiAddrLocationMap エントリの数。マッピング情報が提供されない場合はゼロ。
|
map | const jvmtiAddrLocationMap* |
ネイティブ・アドレスと位置のマッピング。各エントリのネイティブ・アドレス範囲は、start_address から次のエントリのstart_address-1 まで。マッピング情報が提供されない場合はNULL 。
|
compile_info | const void* |
VM固有のコンパイル情報。参照されるコンパイル情報は、VMによって管理され、収集のためにエージェントに依存していてはならない。この情報の内容と寿命は、VM実装によって定義される。
|
コンパイル済みメソッドのアンロード
void JNICALL
CompiledMethodUnload(jvmtiEnv *jvmti_env,
jmethodID method,
const void* code_addr)
コンパイル済メソッドがメモリーからアンロードされた時点で送信されます。このイベントは、アンロードを実行したスレッド上で送信されない可能性があります。このイベントは、アンロード発生後少し経ってから送信される可能性がありますが、新しく生成されたコンパイル済メソッドによってメモリーが再利用される前に送信されます。このイベントは、クラスのアンロード後に送信される可能性があります。
名前
|
型
|
説明
|
method | jmethodID |
アンロード対象のコンパイル済メソッド。コンパイル済メソッドの識別専用。クラスはアンロードされるため、メソッドを以後のJNIまたはJVM TI関数の引数として使用できない。
|
code_addr | const void* |
コンパイルされたメソッド・コードがロードされたアドレス。コンパイル済メソッドの識別専用。領域が回収済の可能性がある。
|
動的コード生成
void JNICALL
DynamicCodeGenerated(jvmtiEnv *jvmti_env,
const char* name,
const void* address,
jint length)
仮想マシンのコンポーネントが動的に生成された時点で送信されます。これは、コンパイル済のJavaプログラミング言語コードには対応しません。CompiledMethodLoad
を参照してください。これは、コマンド行オプションに応じて異なる内容で生成されるインタープリタなどの、ネイティブ・コード用です。
このイベントには、制御権限はありません。VMは、これらのイベントを生成できない場合、何も送信しません。
これらのイベントは、最初の発生のあと、GenerateEvents
によって送信できます。
名前
|
型
|
説明
|
name | const char* |
コードの名前。修正UTF-8文字列としてエンコードされる。エンドユーザーへの表示用。名前は一意でない可能性がある。
|
address | const void* |
コードのネイティブ・アドレス
|
length | jint |
コードの長さ(バイト単位)
|
データ・ダンプ要求
void JNICALL
DataDumpRequest(jvmtiEnv *jvmti_env)
VMによって送信され、エージェントにデータをダンプするよう要求します。これは単に示唆しているだけであり、エージェントはこのイベントに必ずしも反応する必要はありません。これは、ユーザーからのコマンド行シグナルを処理する場合に便利です。たとえば、Java 2 JDKの場合、Win32上ではCtrl+Breakキー、Solaris上ではCtrl+\キーで、このイベントはVMからエージェントへ送信されます。
競合するモニター開始
void JNICALL
MonitorContendedEnter(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jobject object)
スレッドがJavaプログラミング言語モニターに入ろうとしたとき、そのモニターがすでに別のスレッドによって獲得されている場合に送信されます。
名前
|
型
|
説明
|
jni_env | JNIEnv * |
イベントの現在のスレッドのJNI環境
|
thread | jthread |
モニターに入ろうとするスレッドのJNIローカル参照
|
object | jobject |
モニターのJNIローカル参照
|
競合するモニター開始済み
void JNICALL
MonitorContendedEntered(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jobject object)
別のスレッドがJavaプログラミング言語モニターを解放するのを待ったあとで、スレッドがそのJavaモニターに入るときに送信されます。
名前
|
型
|
説明
|
jni_env | JNIEnv * |
イベントの現在のスレッドのJNI環境
|
thread | jthread |
モニターに入るスレッドのJNIローカル参照
|
object | jobject |
モニターのJNIローカル参照
|
モニター待機
void JNICALL
MonitorWait(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jobject object,
jlong timeout)
スレッドがオブジェクトを待機しようとしているときに送信されます。
名前
|
型
|
説明
|
jni_env | JNIEnv * |
イベントの現在のスレッドのJNI環境
|
thread | jthread |
待機しようとするスレッドのJNIローカル参照
|
object | jobject |
モニターのJNIローカル参照
|
timeout | jlong |
スレッドが待機する時間(単位はミリ秒)。
|
モニター待機終了
void JNICALL
MonitorWaited(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jobject object,
jboolean timed_out)
スレッドがオブジェクトの待機を終了するときに送信されます。
名前
|
型
|
説明
|
jni_env | JNIEnv * |
イベントの現在のスレッドのJNI環境
|
thread | jthread |
待機を終了したスレッドのJNIローカル参照
|
object | jobject |
モニターのJNIローカル参照。
|
timed_out | jboolean |
モニターがタイム・アウトになった場合true
|
リソース不足
void JNICALL
ResourceExhausted(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jint flags,
const void* reserved,
const char* description)
実行中のアプリケーションが必要とするVMリソースが使い果たされたときに送信されます。任意の権限によって必要とされるものを除けば、不足を報告するリソース・セットは実装に依存します。
次のビット・フラグは、リソース不足のプロパティを定義します。
定数
|
値
|
説明
|
JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | 0x0001 |
このイベントが返されたあと、VMはjava.lang.OutOfMemoryError をスローする。
|
JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP | 0x0002 |
VMが、JavaTMプラットフォームのヒープからメモリーを割り当てることができなかった。ヒープとは、すべてのクラス・インスタンスおよび配列のメモリーの割当て元となる実行時データ領域のことである。
|
JVMTI_RESOURCE_EXHAUSTED_THREADS | 0x0004 |
VMがスレッドを作成できなかった。
|
名前
|
型
|
説明
|
jni_env | JNIEnv * |
イベントの現在のスレッドのJNI環境
|
flags | jint |
リソース不足フラグで指定される、リソース不足のプロパティを定義するフラグ。
|
reserved | const void* |
予約済み。
|
description | const char* |
リソース不足の説明。修正UTF-8文字列としてエンコードされる。
|
VMオブジェクト割当て
void JNICALL
VMObjectAlloc(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jobject object,
jclass object_klass,
jlong size)
メソッドによって、仮想マシンがJavaプログラミング言語コードに対して可視のオブジェクトを割り当て、その他の実装メカニズムがこの割り当てを検出できない場合に送信されます。通常、オブジェクトの割当ては、割り当てるメソッドのバイト・コードを実装することによって検出されます。JNI関数呼出しにより、ネイティブ・コードで生成されたオブジェクト割当ては、JNI関数の遮断によって検出されます。バイト・コードに関連付けられておらず、ネイティブでないメソッドは、VMによって直接実行されます。このイベントは、これらのメソッドによって送信されます。仮想マシンが、これらのメソッドの一部またはすべてに対してバイト・コードを実装できない場合、このイベントが送信されることがあります。
次に、このイベントが送信される典型的な事例を示します。
- リフレクション -- たとえば、
java.lang.Class.newInstance()
- バイト・コードで表されていないメソッド -- たとえば、VMの組込みメソッドとJ2MEプリロード・クラス
次の場合、このイベントは生成されません。
- バイト・コードによる割り当て -- たとえば、
new
およびnewarray
VM命令
- JNI関数呼出しによる割り当て -- たとえば、
AllocObject
- VM初期化中の割当て
- VM内部オブジェクト
オブジェクトの解放
void JNICALL
ObjectFree(jvmtiEnv *jvmti_env,
jlong tag)
オブジェクトの解放イベントは、ガベージ・コレクタがオブジェクトを解放した時点で送信されます。イベントは、タグ付きオブジェクトの場合にのみ送信されます(「ヒープ関数」を参照)。
イベント・ハンドラは、特別に使用が許可されているJVM TI関数以外の関数およびJNI関数を使用できません(rawモニター関数、メモリー管理関数、環境ローカル記憶領域関数を参照)。
名前
|
型
|
説明
|
tag | jlong |
解放されるオブジェクトのタグ
|
ガベージ・コレクションの開始
void JNICALL
GarbageCollectionStart(jvmtiEnv *jvmti_env)
ガベージ・コレクションの開始イベントは、ガベージ・コレクションによる一時停止が開始されたとき送信されます。処理を停止する(stop-the-world)コレクション、つまりすべてのスレッドがJava仮想マシンのステータスの変更を終了している間に収集されるコレクションだけがレポートされます。このため、コレクタによっては、これらのイベントを生成しません。このイベントは、VMがまだ停止している間に送信されるので、イベント・ハンドラは、JNI関数、およびJVM TI関数(特別にそのような使用が許可されているものを除く)を使用してはいけません(rawモニター、メモリー管理、および環境ローカル記憶領域関数を参照)。
このイベントは、常にGarbageCollectionFinish
と一致するペア(どちらのイベントも有効と見なされる)として送信され、これらの間に、ガベージ・コレクション・イベントは発生しません。
ガベージ・コレクションの完了
void JNICALL
GarbageCollectionFinish(jvmtiEnv *jvmti_env)
ガベージ・コレクションの終了イベントは、ガベージ・コレクションによる一時停止が終了したとき送信されます。このイベントは、VMがまだ停止している間に送信されるので、イベント・ハンドラは、JNI関数、およびJVM TI関数(特別にそのような使用が許可されているものを除く)を使用してはいけません(rawモニター、メモリー管理、および環境ローカル記憶領域関数を参照)。
一部のエージェントは、許可されていないJVM TIまたはJNI関数を使用する必要のある、ガベージ・コレクション後の操作を行う必要があります。そのような場合、rawモニターで待機するエージェント・スレッドを作成でき、ガベージ・コレクションの終了イベントでは、単にrawモニターに通知します。
このイベントは、常にGarbageCollectionStart
と一致するペア(どちらのイベントも有効と見なされる)として送信されます。
定数の索引
JVMTI_CLASS_STATUS_ARRAY
JVMTI_CLASS_STATUS_ERROR
JVMTI_CLASS_STATUS_INITIALIZED
JVMTI_CLASS_STATUS_PREPARED
JVMTI_CLASS_STATUS_PRIMITIVE
JVMTI_CLASS_STATUS_VERIFIED
JVMTI_DISABLE
JVMTI_ENABLE
JVMTI_HEAP_FILTER_CLASS_TAGGED
JVMTI_HEAP_FILTER_CLASS_UNTAGGED
JVMTI_HEAP_FILTER_TAGGED
JVMTI_HEAP_FILTER_UNTAGGED
JVMTI_HEAP_OBJECT_EITHER
JVMTI_HEAP_OBJECT_TAGGED
JVMTI_HEAP_OBJECT_UNTAGGED
JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT
JVMTI_HEAP_REFERENCE_CLASS
JVMTI_HEAP_REFERENCE_CLASS_LOADER
JVMTI_HEAP_REFERENCE_CONSTANT_POOL
JVMTI_HEAP_REFERENCE_FIELD
JVMTI_HEAP_REFERENCE_INTERFACE
JVMTI_HEAP_REFERENCE_JNI_GLOBAL
JVMTI_HEAP_REFERENCE_JNI_LOCAL
JVMTI_HEAP_REFERENCE_MONITOR
JVMTI_HEAP_REFERENCE_OTHER
JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN
JVMTI_HEAP_REFERENCE_SIGNERS
JVMTI_HEAP_REFERENCE_STACK_LOCAL
JVMTI_HEAP_REFERENCE_STATIC_FIELD
JVMTI_HEAP_REFERENCE_SUPERCLASS
JVMTI_HEAP_REFERENCE_SYSTEM_CLASS
JVMTI_HEAP_REFERENCE_THREAD
JVMTI_HEAP_ROOT_JNI_GLOBAL
JVMTI_HEAP_ROOT_JNI_LOCAL
JVMTI_HEAP_ROOT_MONITOR
JVMTI_HEAP_ROOT_OTHER
JVMTI_HEAP_ROOT_STACK_LOCAL
JVMTI_HEAP_ROOT_SYSTEM_CLASS
JVMTI_HEAP_ROOT_THREAD
JVMTI_ITERATION_ABORT
JVMTI_ITERATION_CONTINUE
JVMTI_ITERATION_IGNORE
JVMTI_JAVA_LANG_THREAD_STATE_BLOCKED
JVMTI_JAVA_LANG_THREAD_STATE_MASK
JVMTI_JAVA_LANG_THREAD_STATE_NEW
JVMTI_JAVA_LANG_THREAD_STATE_RUNNABLE
JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED
JVMTI_JAVA_LANG_THREAD_STATE_TIMED_WAITING
JVMTI_JAVA_LANG_THREAD_STATE_WAITING
JVMTI_JLOCATION_JVMBCI
JVMTI_JLOCATION_MACHINEPC
JVMTI_JLOCATION_OTHER
JVMTI_KIND_ALLOC_ALLOC_BUF
JVMTI_KIND_ALLOC_BUF
JVMTI_KIND_IN
JVMTI_KIND_IN_BUF
JVMTI_KIND_IN_PTR
JVMTI_KIND_OUT
JVMTI_KIND_OUT_BUF
JVMTI_PHASE_DEAD
JVMTI_PHASE_LIVE
JVMTI_PHASE_ONLOAD
JVMTI_PHASE_PRIMORDIAL
JVMTI_PHASE_START
JVMTI_PRIMITIVE_TYPE_BOOLEAN
JVMTI_PRIMITIVE_TYPE_BYTE
JVMTI_PRIMITIVE_TYPE_CHAR
JVMTI_PRIMITIVE_TYPE_DOUBLE
JVMTI_PRIMITIVE_TYPE_FLOAT
JVMTI_PRIMITIVE_TYPE_INT
JVMTI_PRIMITIVE_TYPE_LONG
JVMTI_PRIMITIVE_TYPE_SHORT
JVMTI_REFERENCE_ARRAY_ELEMENT
JVMTI_REFERENCE_CLASS
JVMTI_REFERENCE_CLASS_LOADER
JVMTI_REFERENCE_CONSTANT_POOL
JVMTI_REFERENCE_FIELD
JVMTI_REFERENCE_INTERFACE
JVMTI_REFERENCE_PROTECTION_DOMAIN
JVMTI_REFERENCE_SIGNERS
JVMTI_REFERENCE_STATIC_FIELD
JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP
JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR
JVMTI_RESOURCE_EXHAUSTED_THREADS
JVMTI_THREAD_MAX_PRIORITY
JVMTI_THREAD_MIN_PRIORITY
JVMTI_THREAD_NORM_PRIORITY
JVMTI_THREAD_STATE_ALIVE
JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER
JVMTI_THREAD_STATE_IN_NATIVE
JVMTI_THREAD_STATE_IN_OBJECT_WAIT
JVMTI_THREAD_STATE_INTERRUPTED
JVMTI_THREAD_STATE_PARKED
JVMTI_THREAD_STATE_RUNNABLE
JVMTI_THREAD_STATE_SLEEPING
JVMTI_THREAD_STATE_SUSPENDED
JVMTI_THREAD_STATE_TERMINATED
JVMTI_THREAD_STATE_VENDOR_1
JVMTI_THREAD_STATE_VENDOR_2
JVMTI_THREAD_STATE_VENDOR_3
JVMTI_THREAD_STATE_WAITING
JVMTI_THREAD_STATE_WAITING_INDEFINITELY
JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT
JVMTI_TIMER_ELAPSED
JVMTI_TIMER_TOTAL_CPU
JVMTI_TIMER_USER_CPU
JVMTI_TYPE_CCHAR
JVMTI_TYPE_CVOID
JVMTI_TYPE_JBOOLEAN
JVMTI_TYPE_JBYTE
JVMTI_TYPE_JCHAR
JVMTI_TYPE_JCLASS
JVMTI_TYPE_JDOUBLE
JVMTI_TYPE_JFIELDID
JVMTI_TYPE_JFLOAT
JVMTI_TYPE_JINT
JVMTI_TYPE_JLONG
JVMTI_TYPE_JMETHODID
JVMTI_TYPE_JNIENV
JVMTI_TYPE_JOBJECT
JVMTI_TYPE_JSHORT
JVMTI_TYPE_JTHREAD
JVMTI_TYPE_JVALUE
JVMTI_VERBOSE_CLASS
JVMTI_VERBOSE_GC
JVMTI_VERBOSE_JNI
JVMTI_VERBOSE_OTHER
JVMTI_VERSION_INTERFACE_JNI
JVMTI_VERSION_INTERFACE_JVMTI
JVMTI_VERSION_MASK_INTERFACE_TYPE
JVMTI_VERSION_MASK_MAJOR
JVMTI_VERSION_MASK_MICRO
JVMTI_VERSION_MASK_MINOR
JVMTI_VERSION_SHIFT_MAJOR
JVMTI_VERSION_SHIFT_MICRO
JVMTI_VERSION_SHIFT_MINOR
JVMTI_VISIT_ABORT
JVMTI_VISIT_OBJECTS
変更履歴
最終更新日: 09/05/07
バージョン: 1.2.3
JVM TI仕様は発展中のドキュメントであり、メジャー、マイナー、マイクロの各バージョン番号を持ちます。リリース版の仕様はメジャー・バージョンとマイナー・バージョンで一意に識別されます。この仕様に含まれる関数、イベント、権限には「導入されたバージョン」値が示されていますが、これは、その機能が導入されたメジャー・バージョンとマイナー・バージョンです。VMが実装する仕様のバージョンを実行時に取得するには、GetVersionNumber
関数を使用します。
バージョン 日付 | 変更点 |
2002年11月14日 |
XML文書に変換。
|
2002年11月14日 |
ヒープ・ダンプ関数の記述に誤りがあったため、一時的に内容を削除。
|
2002年11月18日 |
詳しいスループットを追加。
|
2002年11月18日 |
JVMTI_THREAD_STATUS_RUNNINGをJVMTI_THREAD_STATUS_RUNNABLEに変更。
|
2002年11月19日 |
AsyncGetStackTraceを追加。
|
2002年11月19日 |
GetStackTraceの戻り値jframeIDを追加。
|
2002年11月19日 |
GetCurrentFrame関数とGetCallingFrame関数の記述にGetStackTraceと重複する点があったため、一時的に内容を削除。
|
2002年11月19日 |
重複したClearAllBreakpointsを削除。
|
2002年11月19日 |
GetSystemPropertiesを追加。
|
2002年11月19日 |
スレッド・ローカルな記憶領域関数がjthreadを使用するように変更。
|
2002年11月20日 |
GetJLocationFormatを追加。
|
2002年11月22日 |
イベントと概要のテキストを追加。
|
2002年11月22日 |
型と定数の定義のクロス・リファレンスを追加。
|
2002年11月24日 |
DTDを追加。
|
2002年11月24日 |
権限関数のセクションを追加。
|
2002年11月29日 |
各関数およびイベントに権限を割当て。
|
2002年11月29日 |
JNI遮断関数を追加。
|
2002年11月30日 |
SetEventNotificationMode権限を自動生成。
|
2002年11月30日 |
VMObjectAlloc イベントを追加。
|
2002年11月30日 |
DynamicCodeGenerated イベントを追加。
|
2002年11月30日 |
宣言の定数を追加。
|
2002年11月30日 |
メソッドの終了とフレーム・ポップが例外を送信するように変更。
|
2002年12月1日 |
ForceGarbageCollectionを追加。
|
2002年12月2日 |
Xrunセクションの改訂: GetStackTraceの説明をわかりやすく変更し、例を追加。幅の問題を修正。「エージェント」を矛盾なく使用。
|
2002年12月8日 |
以前の概要情報を削除。「JVM TI環境」セクションを追加。
|
2002年12月8日 |
DisposeEnvironment を追加します。
|
2002年12月9日 |
多数の細かい更新。
|
2002年12月15日 |
ヒープ・プロファイリング関数を追加: 注釈の取得/設定、ライブ・オブジェクト/ヒープの反復処理。ヒープ・プロファイリング関数のプレースホルダーを追加: ヒープ・ルート。ヒープ・プロファイリング・イベントを追加: オブジェクトの解放。ヒープ・プロファイリング・イベントを再設計: VMオブジェクト割当て。ヒープ・プロファイリング・イベントのプレースホルダーを追加: ガベージ・コレクションの開始/終了。ネイティブ・メソッド・バインド・イベントを追加。
|
2002年12月19日 |
関数の中断/再開の説明を改訂。jvmdiタグ付きの元の情報を追加。その他の修正。
|
2002年12月24日 |
型にセマンティックスを追加。
|
2002年12月27日 |
ローカル参照のセクションを追加。型からパラメータの説明を自動生成。
|
2002年12月28日 |
RunAgentThreadがthreadStartを送信することを文書化。
|
2002年12月29日 |
重複したローカル参照と割当て解除の警告を削除。GetRawMonitorNameを割当て済みバッファに変換。GenerateEventsを追加。
|
2002年12月30日 |
rawモニターを型に変更し、名前をjrawMonitorIDに変更。
|
2003年1月1日 |
元の情報を追加。JVMDIの問題の参照を整理。Deallocateの警告が自動生成されるようになったので削除。
|
2003年1月2日 |
jthreadの表現の問題を修正。
|
2003年1月3日 |
権限を64ビットにバッファ・アウト(自動処理)。
|
2003年1月4日 |
列挙の定数を列挙型に変更。パラメータは列挙型。型のセクションを整理し、索引を作成。残っているデータ定義エンティティをコールバックで置換え。
|
2003年1月7日 |
GenerateEventsの説明を修正。より多くの内部セマンティックスを有効化。
|
2003年1月9日 |
以前のGetSystemPropertiesを、固定情報ではなく割り当てられた情報を使用する2つの関数で置換え。SetSystemPropertyを追加。より多くの内部セマンティックスを有効化。
|
2003年1月12日 |
SetEventNotificationModeの末尾に可変引数を追加。
|
2003年1月20日 |
割当てサイズがjlongであることを反映するように仕様を修正。
|
2003年1月22日 |
RunAgentThreadの引数としてNULLを許可。
|
2003年1月22日 |
標準命名規則Removed AsyncGetStackTraceの名前を修正。
|
2003年1月29日 |
jthreadを使用するためGetThreadを削除。
|
2003年1月31日 |
GetMethodNameと同様にNULLを許可するようにGetFieldNameを変更。
|
v40 2003年2月29日 |
概要のテキストを書き直し、起動、環境、およびバイト・コード・インストゥルメンテーションに関するセクションを追加。EGディスカッションに従ってコマンド行引数を変更。権限のセクションに概要情報を追加。拡張メカニズムのカテゴリと関数を追加。SuspendAllThreadsの削除を指定(説明を改訂)。IterateOverLiveObjectsの名前をIterateOverReachableObjectsに変更し、この変更に応じてテキストも変更。IterateOverHeapの説明を改訂。CompiledMethodLoadの説明を改訂。関数呼出しの必要条件について検討。SetAllocationHooksの説明を改訂。全体にわたって「解決予定」として問題を追加。その他。
|
v41 2003年3月6日 |
GetOwnedMonitorInfoの呼出しから構造体を削除。大部分のエラー・ドキュメントを自動生成。手書きの(不規則な)エラー・ドキュメントを削除。権限の使用に関する説明を改善(空の初期セット)。jintパラメータに最小値を追加。権限can_access_thread_local_storageを削除。エラーJVMTI_ERROR_NOT_IMPLEMENTEDをJVMTI_ERROR_MUST_POSSESS_CAPABILITYに名称変更。*NOT_IMPLEMENTEDについても同様。説明を修正。
|
v42 2003年3月8日 |
GetClassSignatureの名前をGetClassNameに変更。IterateOverClassObjectsの名前をIterateOverInstancesOfClassに変更。GetMaxStackを削除(オペランド・スタックはJVM TIでは使用されない)。説明を修正: 起動時間の定義、PopFrameからのネイティブ・フレーム・ポップの削除、その他の改訂。
|
v43 2003年3月8日 |
細かい編集上の問題を修正。
|
v44 2003年3月10日 |
段階の情報を追加。イベント番号を再マップ(コンパクト化)。
|
v45 2003年3月11日 |
段階の情報をさらに追加 -「すべて」を許可。rawモニターの照会およびイベントを削除。説明の細かい修正。
|
v46 2003年3月12日 |
GetPhaseを追加。文書全体で「段階」を使用。GetRawMonitorNameを削除。GetObjectMonitorsを削除。
|
v47 2003年3月12日 |
リンク、XML、スペル・チェックによる修正。コールバック構造体を自動生成。
|
v48 2003年3月13日 |
1文字のXMLを修正。
|
v49 2003年3月13日 |
イベント・パラメータ名と対応するように関数パラメータ名を変更(fooBarBazをfoo_bar_bazに変更)。
|
v50 2003年3月14日 |
壊れたリンクを修正。スレッド・マーカーを修正。
|
v51 2003年3月14日 |
コンパイラの問題を回避するため、128より小さくなるように定数を変更。
|
v52 2003年3月23日 |
権限について全面的に見直し。GetStackTraceをGetStackTraceとGetStackFramesに分割。
|
v54 2003年4月8日 |
フレームの参照に、jframeIDではなく深さを使用。不適切になったGetCurrentFrame、GetCallerFrame、およびGetStackFramesを削除。イベントからフレーム引数を削除。
|
v55 2003年4月9日 |
テストにより、バッファを使用するほうが効率がよいとわかったため、GetObjectWithAnnotationを削除。GetObjectsWithAnnotationsにannotation_countを追加
|
v56 2003年4月10日 |
GetObjectsWithAnnotationsに挿入されたあいまいな記述を削除
|
v58 2003年4月13日 |
メソッドのjclass/jmethodIDという表現を単なるjmethodIDで置換え。すべてのイベントの第1引数としてJvmtiEnv*を渡す。不適切な箇所からJNIEnv*を削除。can_access_framesをcan_access_local_variablesで置換え。純粋なスタック・アクセスから削除。can_get_synthetic_attributeを使用。説明を修正。長さゼロの配列は割当て解除する必要があることを明記。RelinquishCapabilitiesの説明を明確化。JVMTI_ERROR_VM_DEADをJVMTI_ERROR_WRONG_PHASEに一般化。
|
v59 2003年4月27日 |
OBSOLETE_METHOD_IDの不要な間接参照を削除。
|
v60 2003年5月4日 |
OnLoad時のDestroyRawMonitorを許可。
|
v61 2003年5月7日 |
DestroyRawMonitorにモニターの所有者でない場合に返されるエラーを追加。
|
v62 2003年5月13日 |
rawモニターのセマンティックスを改訂。GetThreadStatus のフラグを変更。GetClassLoader は、ブートストラップ・クラス・ローダーの場合NULLを返す。GetClassName の問題を追加。局所変数シグニチャを定義。GetObjectsWithAnnotations の注釈配列内のゼロを禁止。GetObjectsWithAnnotations の仕様を削除。SetAllocationHooks を削除します。SuspendAllThreads を削除します。
|
v63 2003年5月14日 |
データ型jvmtiEventCallbacks を定義。ゼロ長の割当てはNULLを返す。SetAllocationHooksはJVMDIでは保持されるがJVM TIからは削除。JVMTI_THREAD_STATUS_FLAG_INTERRUPTEDを追加。
|
v64 2003年5月15日 |
レビューにより表現を変更。
|
v65 2003年5月15日 |
最初のアルファ版。jmethodIDとjfieldIDを一意に変更。jclassは使用しない。
|
v66 2003年5月27日 |
細かいXSLTエラーを修正。
|
v67 2003年6月13日 |
jfieldIDの一意化を取り消し(jmethodIDはそのまま)。
|
v68 2003年6月17日 |
6月11日のExpert Groupミーティングによる変更 -- ヒープ関数の見直し: シングル・コールバック、GetHeapRootsの削除、到達可能なイテレータの追加、「注釈」の名前を「タグ」に変更。ほとんどの関数で、NULLスレッド・パラメータは現在のスレッド。タイマーを追加。ForceExitを削除。GetEnvironmentLocalStorageを追加。冗長フラグおよびイベントを追加。AddToBootstrapClassLoaderSearchを追加。ClassFileLoadHookを更新。
|
v69 2003年6月18日 |
問題点のセクションを改訂。GetClassNameの名前をGetClassSignatureに戻し、説明を修正。GetClassSignature、GetFieldSignature、GetMethodSignature、およびGetLocalVariableTableにジェネリック・シグニチャを追加。EstimateCostOfCapabilitiesを削除。システム・プロパティ関数がシステム・プロパティのVMビューで動作することを明示。Agent_OnLoadの説明を改訂。イベントのJNIEnv*から定数を削除。メタデータ・アクセサを追加。
|
v70 2003年6月18日 |
GetStackTraceにstart_depthを追加。システム・プロパティを新しいカテゴリに移動。GetObjectSizeを追加。コマンド行フラグからXを削除。XML、HTML、スペル・チェックによる修正。
|
v71 2003年6月19日 |
JVMTI_HEAP_ROOT_THREADを6に修正。各説明が関数名に一致するように変更。あいまいな表現を修正。
|
v72 2003年6月26日 |
SetThreadLocalStorageとSetEnvironmentLocalStorageでは、値をNULLに設定できなければならない。NotifyFramePop、GetFrameLocationm、およびフレームについて記述する必要があるすべての局所変数の操作を修正。全体にわたって、文法を修正し、説明を明瞭化する必要がある。大文字と小文字の区別、および句読点に一貫性を持たせる必要がある。マイクロ・バージョン番号と、メジャー、マイナー、およびマイクロ・バージョン番号にアクセスするマスクが必要。エラー・コード・リストに、実装によって返されるエラー・コードを示す必要がある。コマンド行プロパティをプロパティ関数内で可視にする必要がある。現在のスレッドからのポップを禁止。ポップできないとき、実装が不透明なフレーム・エラーを返すことを許可。NativeMethodBindイベントは、どの段階でも送信できなければならない。DynamicCodeGeneratedイベントは、どの段階でも送信できなければならない。VMInitの前に、次の関数の実行が許可されなければならない: Set/GetEnvironmentLocalStorage GetMethodDeclaringClass GetClassSignature GetClassModifiers IsInterface IsArrayClass GetMethodName GetMethodModifiers GetMaxLocals GetArgumentsSize GetLineNumberTable GetMethodLocation IsMethodNative IsMethodSynthetic。XSLに対するその他の変更: 引数の説明で、ポインタの前ではなく後ろにアスタリスクを表示する必要がある。NotifyFramePop、GetFrameLocationm、およびその他の局所変数の操作にNO_MORE_FRAMESエラーを追加する必要がある。活動状態でないスレッドは、無効なスレッドとは異なったエラーを返す必要がある。
|
v73 2003年7月7日 |
VerboseOutputイベントがメッセージ・パラメータを検出しなかった。細かい修正。
|
v74 2003年7月14日 |
Technical Publications Departmentによる修正。スレッド・ローカルおよび環境ローカルな記憶領域にNULLを設定することを許可。
|
v75 2003年7月23日 |
オーバーロードされたJVM_OnLoadの代わりに新しいAgent_OnLoadを使用。コールバックにJNICALLを追加(XSL)。イベントとコールバックの両方についてJNICALLの要件を文書化(XSL)。RedefineClassesをメソッドと属性に限定。VerboseOutputイベントを削除。VMObjectAlloc: イベント送信時に制限し、メソッド・パラメータを削除。Tech Pubsによる編集に対する対応を完了。
|
v76 2003年7月24日 |
ClassFileLoadHookイベントが再定義のブール型ではなくクラスを送信するように変更。
|
v77 2003年7月24日 |
XMLファイル。テキストの細かい部分の改訂と修正。
|
v78 2003年7月24日 |
JVM TIからGetExceptionHandlerTableとGetThrownExceptionsを削除。スタック・フレームがJVM仕様のフレームであることを明記。can_get_source_infoをcan_get_source_file_name、can_get_line_numbers、およびcan_get_source_debug_extensionに分割。PopFrameはネイティブ呼出しメソッドを持つことができない。GetClassloaderClassesから正確でない記述を削除(Java(tm)仮想マシン仕様のセクション4.4を参照)。
|
v79 2003年7月24日 |
XMLおよびテキストを修正。スタック・フレームの説明をスタック・フレーム・カテゴリに移動。
|
v80 2003年7月26日 |
GetClassloaderClassesにNULL (ブートストラップ・ローダー)を許可。クラスからの参照に新しいヒープ参照の種類を追加。タイマー情報の構造体とクエリー関数を追加。AvailableProcessorsを追加。GetOtherThreadCpuTimeの名前をGetThreadCpuTimeに変更。SetEventNotificationモードにJVMTI_ERROR_INVALID_THREADとJVMTI_ERROR_THREAD_NOT_ALIVEを明示的に追加。VM_INITイベントに初期スレッドを追加。AddToBootstrapClassLoaderSearchからプラットフォームの仮定条件を削除。
|
v81 2003年7月26日 |
レビューにより、文法と表現を変更。
|
v82 2003年7月27日 |
レビューにより、文法と表現をさらに変更。Agent_OnUnloadを追加。
|
v83 2003年7月28日 |
Agent_OnUnloadの戻り型をvoidに変更。
|
v84 2003年7月28日 |
JVMTI_REFERENCE_ARRAYの名前をJVMTI_REFERENCE_ARRAY_ELEMENTに変更。
|
v85 2003年7月28日 |
AvailableProcessors()のjava.lang.Runtime.availableProcessors()の表現を借用。イベントIDがゼロにならないことを保証。解決された問題を削除。レビューにより、タイマー情報関数の名前を変更、説明を補足。
|
v86 2003年7月29日 |
XMLで制御される実装に対して、仕様に影響のない変更を追加: SetThreadLocalStorageはVMモードで実行する必要がある。
|
0.1.87 2003年8月5日 |
GetErrorNameを追加。jvmtiExtensionEventに可変引数の警告を追加。jvmtiExtensionEventのjvmtiEnv*から定数を削除。使用されないcan_get_exception_info権限を削除。jvmtiStartFunctionにjvmtiEnv*とJNIEnv*を渡す。jvmtiExtensionFunctionInfo.funcの宣言型を修正。拡張関数はエラー・コードを返す。バージョン番号付け方式を新規化。
|
0.2.88 2003年8月5日 |
ClassUnloadイベントを削除。
|
0.2.89 2003年8月8日 |
ヒープ参照イテレータのコールバックは、出力オブジェクト参照の無視を許可する列挙型を返す。JNIEnvを拡張イベント/拡張関数のパラメータ型として許可。
|
0.2.90 2003年8月15日 |
タイプ・ミスを修正。
|
0.2.91 2003年9月2日 |
すべてのメタデータ関数を削除: GetClassMetadata、GetFieldMetadata、およびGetMethodMetadata。
|
0.2.92 2003年10月1日 |
関数Allocateにマーク付け。Deallocate、RawMonitor*、SetEnvironmentLocalStorage、およびGetEnvironmentLocalStorageをヒープ・コールバックおよびGCイベント内で安全に使用できるものとする。
|
0.2.93 2003年11月24日 |
ヒープ反復関数およびコールバックにパススルーが不透明なユーザー・データ・ポインタを追加。CompiledMethodUnloadイベントで、コード・アドレスを送信する。GarbageCollectionOccurredイベントを追加。定数プール参照の種類を追加。関数CreateRawMonitorおよびDestroyRawMonitorをヒープ・コールバックおよびGCイベント内で安全に使用できるものとする。説明を改訂: VMDeath、GetCurrentThreadCpuTimerInfo、GetThreadCpuTimerInfo、IterateOverReachableObjects、IterateOverObjectsReachableFromObject、GetTime、およびJVMTI_ERROR_NULL_POINTER。欠落していたエラーを追加: GenerateEventsおよびAddToBootstrapClassLoaderSearch。ClassFileLoadHook名前パラメータの説明を修正。ヒープ・コールバックおよびGC/ObjectFreeイベント内で、明示的に許可された関数しか呼び出せないように指定。コールバック中、GetCurrentThreadCpuTimerInfo、GetCurrentThreadCpuTime、GetTimerInfo、およびGetTimeを許可。OnLoad段階でのSetTag/GetTagの呼出しを許可。SetEventNotificationModeに追加: 不適切なスレッド・レベルでの制御を試行した場合のエラー。jvmtiExceptionHandlerEntryを削除。スタックのネイティブ・メソッドの処理を修正 -- GetFrameLocationのlocation_ptrパラメータ、GetFrameLocation、jvmtiFrameInfo.location、およびjlocationからJVMTI_ERROR_OPAQUE_FRAMEを削除。スリープ時にMonitorWaitedイベントが送信されるという意味になってしまっているタイプ・ミスを削除(JVMPIより)。
|
0.2.94 2003年11月25日 |
説明の改訂とタイプ・ミスの修正。
|
0.2.95 2003年12月3日 |
ヒープ・イテレータでのNULL user_dataを許可。
|
0.2.97 2004年1月28日 |
GetThreadStateを追加し、GetThreadStatusを非推奨にする。
|
0.2.98 2004年1月29日 |
INVALID_SLOTおよびTYPE_MISMATCHエラーはオプションにしなければならない。
|
0.2.102 2004年2月12日 |
MonitorContendedExitを削除。JNIEnvパラメータをVMObjectAllocに追加。ヒープ・コールバックのclass_tagおよびreferrer_indexパラメータを明示的に定義。
|
0.2.103 2004年2月16日 |
JAVA_TOOL_OPTIONSのドキュメント化。
|
0.2.105 2004年2月17日 |
開始段階を初期段階と開始段階とに分割。関数やイベントのVMStartイベント変更段階関連を追加。
|
0.3.6 2004年2月18日 |
非推奨になっていたGetThreadStatusを削除。マイナー・バージョンを上げ、マイクロ・バージョンから100を引く
|
0.3.7 2004年2月18日 |
タイマーのナノ秒値が符号なしであることをドキュメント化。ネイティブ・メソッドに関連するテキストを改訂。
|
0.3.8 2004年2月19日 |
タイプ・ミスを修正。削除した非推奨のGetThreadStatusを削除。
|
0.3.9 2004年2月23日 |
中断したスレッドでNotifyFramePopを実行しなければならない。
|
0.3.10 2004年2月24日 |
一部のクラスを変更できないように、権限(can_redefine_any_class およびcan_generate_all_class_hook_events )およびエラー(JVMTI_ERROR_UNMODIFIABLE_CLASS )を追加。
|
0.3.11 2004年2月28日 |
JVMTI_ERROR_MUST_POSSESS_CAPABILITYをSetEventNotificationModeに追加。
|
0.3.12 2004年3月8日 |
CompiledMethodUnloadを明確にし、クラスのアンロード後にイベントがポストされる場合があることを明示。
|
0.3.13 2004年3月5日 |
VMObjectAllocのsizeパラメータをjlongに変更し、GetObjectSizeに合わせる。
|
0.3.14 2004年3月13日 |
JNI FindClass関数をイベント・コールバック関数で使用するためのガイドラインを追加。
|
0.3.15 2004年3月15日 |
GetAllStackTracesおよびGetThreadListStackTracesを追加。
|
0.3.16 2004年3月19日 |
ClassLoadおよびClassPrepareイベントは、開始段階中にポストできる。
|
0.3.17 2004年3月25日 |
JVMTI_ERROR_NATIVE_METHODをGetLineNumberTable、GetLocalVariableTable、GetMaxLocals、GetArgumentsSize、GetMethodLocation、GetBytecodesに追加。
|
0.3.18 2004年3月29日 |
タイマー情報構造体のタイマーの種類を返す。
|
0.3.19 2004年3月31日 |
仕様の明確化: JVMTI_THREAD_STATE_IN_NATIVEにはJNIまたはJVM TIを含まない。ForceGarbageCollectionはファイナライザを実行しない。仕様のコンテキストはJavaプラットフォーム。以前のインストゥルメンテーションを警告。
|
0.3.20 2004年4月1日 |
上記で明確化した箇所の改善、およびAgent_OnLoadが返したエラーでVMが終了する。
|
0.3.21 2004年4月1日 |
配列クラスの作成では、クラス・ロード・イベントは生成されません。
|
0.3.22 2004年4月7日 |
スレッド状態の階層をよりjava.lang.Thread.Stateにそろえる。
|
0.3.23 2004年4月12日 |
スレッド状態について明確にした。
|
0.3.24 2004年4月19日 |
エージェントによって実行できるため、GarbageCollectionOccurredイベントを削除。
|
0.3.25 2004年4月22日 |
「コマンド行オプション」を定義。
|
0.3.26 2004年4月29日 |
バイト・コード・インストゥルメンテーションの意図された使用方法を記述。拡張イベントの第1パラメータの説明を修正。
|
0.3.27 2004年4月30日 |
説明の改訂とタイプ・ミスの修正。
|
0.3.28 2004年5月18日 |
DataDumpRequestイベントを削除。
|
0.3.29 2004年5月18日 |
ゼロ・タイムアウトのRawMonitorWaitを明確化。RunAgentThreadのあとのスレッド状態を明確化。
|
0.3.30 2004年5月24日 |
クリーンアップ: 誤ったリンクや古いリンクの修正など。
|
0.3.31 2004年5月30日 |
以下を含む明確化: すべての文字列が修正UTF-8。エージェント・スレッドの可視性。廃止メソッド・バージョンの意味。スレッド呼出ヒープのコールバック
|
1.0.32 2004年6月1日 |
major.minorバージョン番号を"1.0"に変更。
|
1.0.33 2004年6月2日 |
ForceGarbageCollectionとObjectFreeの相互作用を明確化。
|
1.0.34 2004年6月6日 |
AddToBootstrapClassLoaderSearchとSetSystemPropertyをOnLoadフェーズのみに制限。
|
1.0.35 2004年6月11日 |
SetTagのタイプ・ミスを修正。
|
1.0.36 2004年6月18日 |
商標を修正。GetThreadStateの使用法の例にパラメータを追加。
|
1.0.37 2004年8月4日 |
著作権の更新。
|
1.0.38 2004年11月5日 |
欠落していた関数テーブル・レイアウトを追加。欠落していた、関数のC++メンバー関数形式の説明を追加。CFLHの名前がNULLになる可能性があることを明確化。J2SETM 5.0の一部としてリリース。
|
1.1.47 2005年4月24日 |
major.minorバージョン番号を"1.1"に変更。ForceEarlyReturn*関数群を追加。GetOwnedMonitorStackDepthInfo関数を追加。GetCurrentThread関数を追加。「導入されたバージョン」というバージョン・マーカーを追加。AddToSystemClassLoaderSearchを追加。AddToBootstrapClassLoaderSearchのライブ段階での使用を許可。IterateOverHeapおよびIterateOverInstancesOfClass関数のheap_object_callbackパラメータの説明に含まれていた歴史的な不要情報を整理。このパラメータでのNULLの使用を禁止。明確化、修正、一貫性の向上: PopFrameでの現在のスレッド、不透明なフレーム、および不十分な数のフレームに関する表現。「最上位」ではなく「現在のフレーム」を一貫して使用。GetLocal*およびSetLocal*でのJVMTI_ERROR_TYPE_MISMATCHエラーを明確化するため、それらをForceEarlyReturn*での記述と互換性のあるものに変更。他の多くの明確化や表現のクリーン・アップ。
|
1.1.48 2005年4月25日 |
GetConstantPoolの追加。VM仕様の第1版への参照を第2版への参照に切替え。
|
1.1.49 2005年4月26日 |
GetConstantPoolでのマイナー/メジャー・バージョンの順番を明確化。
|
1.1.50 2005年4月26日 |
SetNativeMethodPrefixとSetNativeMethodPrefixesの追加。GetOwnedMonitorStackDepthInfoを位置153に再割当て。「クラス・ローダー検索」を独立したドキュメント・カテゴリとして分離。XMLソース内の長すぎる行を処理。
|
1.1.51 2005年4月29日 |
ライブ段階でのエージェントの起動を許可。エージェントの配備に関する段落を追加。
|
1.1.52 2005年4月30日 |
SetNativeMethodPrefix(es)に仕様の説明を追加。GetConstantPoolの条件の定義を改善。
|
1.1.53 2005年4月30日 |
GetConstantPoolからGetClassVersionNumber関数を分離。VM仕様への参照をクリーンアップ。
|
1.1.54 2005年5月1日 |
SetNativeMethodPrefix(es)の使用を任意の段階で許可。GetConstantPoolへの再定義の影響に関する説明を追加。
|
1.1.56 2005年5月2日 |
SetNativeMethodPrefix(es)に関するさまざまな明確化。
|
1.1.57 2005年5月2日 |
欠落していたパフォーマンス警告をメソッド・エントリ・イベントに追加。
|
1.1.58 2005年5月5日 |
内部的なJVMDIサポートを削除。
|
1.1.59 2005年5月8日 |
RetransformClasses を追加します。バイト・コード・インストゥルメンテーションのドキュメントを再編。IsMethodObsolete がcan_redefine_classes権限を必要としないという記述に変更。
|
1.1.63 2005年5月11日 |
再変換の明確化。
|
1.1.64 2005年5月11日 |
レビューに基づく再変換の明確化。クラス・ロード有効時の「再変換可能(不可能)」を固定。
|
1.1.67 2005年6月4日 |
プリミティブ値の報告をサポートし、参照側のタグ設定を可能にし、より強力なフィルタ・リング機能を備えた、新しいヒープ機能を追加: FollowReferences、IterateThroughHeap、およびそれらに関連するコールバック、構造体、列挙、および定数。
|
1.1.68 2005年6月4日 |
明確化。
|
1.1.69 2005年6月6日 |
FollowReferences、IterateThroughHeap: コールバックを構造体内に配置、欠落していたエラー・コードを追加、ビジット制御フラグのビットを低減。
|
1.1.70 2005年6月14日 |
新ヒープ機能に関する追加作業: レビューに基づく仕様の整理。
|
1.1.71 2005年6月15日 |
新ヒープ機能に関する追加作業: 旧ヒープ・セクションの名前を「ヒープ(1.0)」に変更。
|
1.1.72 2005年6月21日 |
タイプ・ミスを修正。
|
1.1.73 2005年6月27日 |
参照側情報構造体を共用体に変更。
|
1.1.74 2005年9月9日 |
新規ヒープ関数群: 欠落していた参照の種類「スーパー・クラス」を追加。フィールド・インデックスの計算に単一の方式を使用。古くなった構造体ベース参照側情報への参照を削除。
|
1.1.75 2005年9月12日 |
FollowReferences中に、あまり重要でないjava.lang.Objectスーパー・クラス上でコールバックを発生させない。
|
1.1.76 2005年9月13日 |
文字列プリミティブ・コールバックで、長さをUnicode長に変更。配列プリミティブ・コールバックと文字列プリミティブ・コールバックで、値を「const」に変更。JNI関数テーブルの設定時のコンパイラの潜在的な影響についての注を追加。
|
1.1.77 2005年9月13日 |
GetClassVersionNumbers()とGetConstantPool()は、配列またはプリミティブ・クラスの場合にエラーを返すようにする。
|
1.1.78 2005年9月14日 |
文法に関する修正。
|
1.1.79 2005年9月26日 |
IsModifiableClassクエリーを追加。
|
1.1.81 2006年2月9日 |
jvmtiHeapReferenceCallbackにreferrer_class_tagパラメータを追加。
|
1.1.82 2006年2月13日 |
ドキュメント修正: can_redefine_any_classに再変換が含まれるように更新。例外イベントがすべてのThrowableをカバーすることを明記。GetStackTraceでstart_depthがゼロの場合、大きすぎるstart_depthのテストが行われない。プリミティブ・フィールド・コールバックで報告されるフィールドを明確化 -- staticとインスタンス。わかりにくいヒープの型の名前を、コールバック名も含めて修正。スレッド起動メソッドのインタフェースで、スタックの深さの一貫した使用を要求。JVM TIのメモリー管理が他のシステムと非互換であることを述べた注を追加。
|
1.1.85 2006年2月14日 |
タイプ・ミスの修正、名前の変更。
|
1.1.86 2006年3月13日 |
jmethodIDとjfieldIDが保存可能であることを明確化。「クラスのインスタンスの反復」にサブクラスが含まれることを明確化。
|
1.1.87 2006年3月14日 |
表現の修正。
|
1.1.88 2006年3月16日 |
オブジェクト参照コールバック内のstaticフィールドのreferrer_indexが、リファレンス実装(および他のすべての既知の実装)に一致するように変更。つまり、インスタンス・フィールドの定義に一致するように変更。GetThreadListStackTracesで、JVMTI_ERROR_INVALID_THREADを追加してリスト内の無効なスレッドをカバーするようにするとともに、起動されていないスレッドからは空のスタックが返されることを規定。
|
1.1.89 2006年3月17日 |
タイプ・ミス。
|
1.1.90 2006年3月25日 |
タイプ・ミス。
|
1.1.91 2006年4月6日 |
AddToBootstrapClassLoaderSearchとAddToSystemClassLoaderSearchに関する制限を削除。
|
1.1.93 2006年5月1日 |
スタック深さを決定できない実装のモニター・スタックの深さに対して -1を返すように仕様を変更。
|
1.1.94 2006年5月3日 |
IBMのAlan Pratt氏に従って読みやすさと正確さを高めるための修正を実施。FollowReferencesで報告されるオブジェクトの関係を記載。
|
1.1.95 2006年5月5日 |
FollowReferencesで報告されるオブジェクトの関係を明確化。
|
1.1.98 2006年6月28日 |
DisposeEnvironmentの明確化、警告を追加。SetLocalXXXでのタイプ・ミスを修正(「retrieve」=>「set」)。ネイティブ・メソッド接頭辞の使用中は、その接頭辞の設定状態を保つ必要があることを明確化。エージェントごとに厳密に1つのAgent_OnXXXが呼び出されることを明確化。ライブラリのロードは起動に依存しないことを明確化。Agent_OnUnload仕様内でのAgent_OnLoadへのあいまいな参照を削除。
|
1.1.99 2006年7月31日 |
関数と例外との相互作用を明確化。フィールド・インデックスの明確化と具体例の追加。わかりにくい「つまり(That is)」の文を、MonitorWaitおよびMonitorWaitedイベントから削除。Java 6をポイントするようにリンクを更新。
|
1.1.102 2006年8月6日 |
ResourceExhaustedイベントを追加。
|
1.2.2 2012年10月11日 |
LinkCheckツールから報告された「HTTP」および「Missing Anchor」のエラーを修正。
|
1.2.3 2013年6月19日 |
静的リンク・エージェントのサポートを追加。
|