JavaTM Virtual Machine Tool Interface
Version 1.1
|
JVMTI とは
JavaTM Virtual Machine Tool Interface (JVM TI) は、開発ツールや監視ツールで使用されるプログラミングインタフェースです。JVMTI は、JavaTM 仮想マシン (VM) で動作するアプリケーションの状態検査と実行制御の両方の機能を提供し、
プロファイリングツール、デバッグツール、監視ツール、スレッド分析ツール、カバレッジ分析ツールなど、VM の状態その他にアクセスする必要がある各種ツールの VM インタフェースとして機能します。
JVMTI は、JavaTM 仮想マシンのすべての実装で使用できるとは限りません。
JVM TI は、双方向のインタフェースです。以下では、JVM TI のクライアントを「エージェント」と呼びます。エージェントは、イベントから、さまざまな状態の発生通知を受け取ることができます。JVM TI は、イベントに応答して、またはイベントからは独立して、多くの関数を使ってアプリケーションへの照会および制御を実行できます。
個々のエージェントは同一のプロセスで実行され、検査対象のアプリケーションを実行する仮想マシンと直接通信します。この通信には、ネイティブインタ フェース (JVM TI) が使用されます。ネイティブのインプロセスインタフェースにより、ツール側への侵入は最小限に抑えながら、最大限の制御が可能になります。通常、エージェ ントは比較的コンパクトです。エージェントは、ターゲットアプリケーションの通常の実行を妨げることなく、ツールの機能の大部分を実装する別のプロセスによって制御できます。
アーキテクチャー
ツールへの書き込みは、JVM TI を使って直接行われるか、Java プラットフォームツールアーキテクチャーの高度インタフェースを使って間接的に行われます。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 起動時にエージェントを起動するには、コマンド行オプションを使ってエージェントライブラリの名前を指定します。実装によっては、ライブ段階でエージェントを起動する機構をサポートしている可能性があります。その起動方法の詳細は、実装に固有となります。
JVMTI エージェントのコマンド行オプション
以下の「コマンド行オプション」という語は、JNI 呼び出し API の JNI_CreateJavaVM
関数において、JavaVMInitArgs
引数で指定されるオプションを意味します。
エージェントを適切にロードして実行するには、VM の起動時に次のいずれかのコマンド行オプションが必要です。これらの引数は、エージェントを含むライブラリと、起動時に渡されるオプションの文字列を指定します。
-
-agentlib:
<agent-lib-name>=
<options>
-
-agentlib:
の後ろには、ロードするライブラリの名前を指定します。ライブラリのフルネームと場所の検索方法は、プラットフォームによって異なります。通常、<agent-lib-name> は、オペレーティングシステム固有のファイル名に展開されます。 は、起動時にエージェントに渡されます。たとえば、オプション -agentlib:foo=opt1,opt2
が指定された場合、VM は、WindowsTM ではシステムパス PATH
から共有ライブラリ foo.dll
をロードしようとします。SolarisTM オペレーティング環境では、LD_LIBRARY_PATH
から libfoo.so
をロードしようとします。
-
-agentpath:
<path-to-agent>=
<options>
-
-agentpath:
の後ろには、ライブラリをロードする絶対パスを指定します。ライブラリ名の展開は行われません。 は、起動時にエージェントに渡されます。たとえば、オプション -agentpath:c:\myLibs\foo.dll=opt1,opt2
が指定された場合、VM は、共有ライブラリ c:\myLibs\foo.dll
をロードしようとします。
ライブラリ内の起動ルーチン Agent_OnLoad
が呼び出されます。
バイトコードインストゥルメンテーション (bytecode instrumentation) のために必要な場合、ツール内で Java プログラミング言語コードを使用しやすくするため、-agentlib:
または -agentpath:
を指定してロードされたライブラリから、JNI ネイティブメソッド実装が検索されます。
エージェントライブラリは、その他のすべてのライブラリが検索されたあと検索されます。非エージェントメソッドのネイティブメソッド実装を上書きまたは遮断するエージェントは、NativeMethodBind イベントを使用できます。
これらのスイッチは、上記の処理だけを行います。VM や JVM TI の状態を変更することはありません。JVM TI や JVM TI の一部を有効にする処理は、権限 (capability) により、プログラムを通して行われます。コマンド行オプションは必要ありません。
エージェントの起動
VM は、起動関数を呼び出すことで各エージェントを起動します。OnLoad
段階でエージェントを起動する場合は、関数 Agent_OnLoad
が呼び出されます。ライブ段階でエージェントを起動する場合は、関数 Agent_OnAttach
が呼び出されます。起動関数の呼び出しは、エージェントごとに 1 回だけ行われます。
エージェントの起動 (OnLoad 段階)
OnLoad
段階でエージェントを起動する場合、そのエージェントライブラリは次のプロトタイプを持つ起動関数をエクスポートする必要があります。
JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
VM は、この関数を呼び出すことでエージェントを起動します。この呼び出しは VM 初期化の早い段階で行われるため、次のことが言えます。
-
システムプロパティーは、VM の起動で使用される前に設定できる
- すべての権限を使用できる (ただし、VM を構成する権限はこのときしか使用できない。 詳細は「権限関数」セクションを参照)
- バイトコードが実行されていない
- クラスがロードされていない
- オブジェクトが作成されていない
VM は、2 番目の引数として を指定して Agent_OnLoad
関数を呼び出します。つまり、コマンド行オプションの例を使用して、"opt1,opt2"
は Agent_OnLoad
の char *options
引数に渡されます。options
引数は、修正 UTF-8 文字列としてエンコードされます。= が指定されていない場合、options
には長さ 0 の文字列が渡されます。options
文字列は、Agent_OnLoad
呼び出しの間有効です。必要な場合は、この期間が過ぎても、文字列または文字列の一部をコピーする必要があります。Agent_OnLoad
が呼び出されてから終了するまでの期間を「ロード段階」と呼びます。VM はロード段階では初期化されません。このため、Agent_OnLoad
内部で許可された操作は限定されています (この時点で使用可能な機能については関数の説明を参照)。エージェントが安全に実行できるのは、オプションの処理や、SetEventCallbacks
を使ってイベントコールバックを設定する処理です。VM 初期化イベントを受け取ってから (つまり、VMInit コールバックが呼び出されてから)、エージェントは初期化を完了できます。
原理の説明:
早い段階での起動が必要なのは、エージェントが必要な権限を設定できるようにするためです。多くの権限は、VM の初期化前に設定する必要があります。JVMDI では、-Xdebug コマンド行オプションで権限を制御できました。ただし、この制御は非常におおまかなものです。JVMPI 実装は、さまざまなテクニックを使って単一の「JVMPI オン」スイッチを提供します。必要な権限とパフォーマンスへの影響のバランスをとるために必要な細かい制御を提供するのに適したコマンド行オプションはありません。早い段階での起動には、エージェントが各種機能をインストールするため、ファイルシステムやシステムプロパティーに変更を加え、実行環境を制御できるようにする目的もあります。
Agent_OnLoad
の戻り値は、エラーを示すために使用されます。ゼロ以外の値はエラーを表します。エラーが発生すると、VM は終了します。
エージェントの起動 (ライブ段階)
VM によっては、その VM 内でライブ段階でエージェントを起動する機構をサポートしている可能性があります。そのサポート方法の詳細は、実装に固有となります。たとえば、あるツールでは、なんらかのプラットフォーム固有の機構や実装固有の API を使用することで、実行中の VM に接続して特定のエージェントの起動を要求する可能性があります。
ライブ段階でエージェントを起動する場合、そのエージェントライブラリは次のプロトタイプを持つ起動関数をエクスポートする必要があります。
JNIEXPORT jint JNICALL
Agent_OnAttach(JavaVM* vm, char *options, void *reserved)
VM は、この関数を呼び出すことでエージェントを起動します。この呼び出しは、VM に接続されたスレッドのコンテキスト内で行われます。第 1 引数の は、Java VM です。 引数は、エージェントに指定された起動オプションです。 は、修正 UTF-8 文字列としてエンコードされます。起動オプションが指定されなかった場合、options
には長さ 0 の文字列が渡されます。options
文字列は、Agent_OnAttach
呼び出しの間有効です。必要な場合は、この期間が過ぎても、文字列または文字列の一部をコピーする必要があります。
ライブ段階では権限の一部が使用できない可能性があります。
Agent_OnAttach
関数は、エージェントを初期化し、エラーが発生したかどうかを示す値を VM に返します。ゼロ以外の値はすべて、エラーを表します。エラーが発生しても VM は終了しません。代わりに VM は、そのエラーを無視するか、そのエラーを標準エラーに出力したりシステムログに記録したりするなど、なんらかの実装固有のアクションを実行します。
エージェントの停止
ライブラリは、オプションで、次のプロトタイプを持つ停止関数をエクスポートできます。
JNIEXPORT void JNICALL
Agent_OnUnload(JavaVM *vm)
この関数は、ライブラリのアンロードの直前に VM によって呼び出されます。プラットフォーム固有の機構に問題がある場合、アンロードが引き起こされ、この関数が呼び出されます (本書ではアンロード機構は指定しない)。正常な処理もしくは VM の障害 (起動時の障害を含む) によって VM が終了した場合、ライブラリは実際にアンロードされます。もちろん、制御できない停止は、この規則に当てはまりません。この関数と VM Death イベントには違いがあります。VM Death イベントを送信するためには、初期化の前に VM を実行したことがあり、VMDeath のコールバックを設定した有効な JVM TI 環境が存在し、イベントが有効になっている必要があります。これらの条件は、Agent_OnUnload
には不要です。この関数は、ライブラリがその他の理由によってアンロードされたときも呼び出されます。VM Death イベントは、この関数が呼び出される前に送信されます (この関数が VM の終了によって呼び出される場合)。この関数を使って、エージェントによって割り当てられたリソースをクリーンアップすることができます。
埋め込み VM や単にスクリプト内の深い場所で起動される VM などでは、コマンド行のアクセスや変更が常に可能であるとは限らないため、JAVA_TOOL_OPTIONS
変数が用意されています。これを使えば、そうした場合でもエージェントを起動できます。
環境変数やその他の名前付き文字列をサポートするプラットホームでは、JAVA_TOOL_OPTIONS
変数に対応している場合があります。この変数は、オプションを空白文字で区切った文字列です。空白文字には、スペース、タブ、復帰 (CR)、復帰改行 (NL)、垂直タブ、用紙送り (FF) などがあります。連続する空白文字は空白文字 1 文字と同じであるとみなされます。オプションに空白文字を含める場合は、引用符で次のように囲んでください。
- 一重引用符の組 ('') に囲まれた、一重引用符を除くすべての文字は引用として囲まれる。
- 一重引用符の組の内部にある二重引用符には、特殊な意味はない。
- 二重引用符の組 ('') に囲まれた、二重引用符を除くすべての文字は引用として囲まれる。
- 二重引用符の組の内部にある一重引用符には、特殊な意味はない。
- 変数内の任意の場所を引用符で囲むことができる。
- 引用符で囲まれた空白文字には、特殊な意味はない。その他の文字と同様にオプションに含めることができ、区切り文字として機能しない。
- 引用符の組自体はオプションに含まれない。
JNI_CreateJavaVM
(JNI 呼び出し API 内) は、これらのオプションをその JavaVMInitArgs
引数で指定されたオプションの先頭に付加します。プラットホームによっては、セキュリティー上の理由でこの機能を無効にしています。たとえばリファレンス実 装では、有効なユーザーまたはグループの ID が実際の ID と異なる場合に、Unix システム上でこの機能が無効になります。 この機能はツールの初期化、特にネイティブまたは Java プログラミング言語エージェントの起動をサポートするためのものです。複数のツールでこの機能を使用する可能性があります。そのため、変数は上書きせず、オプションを変数に追加するようにしてください。変数が処理されるのは JNI 呼び出し API の VM 作成呼び出し時であるため、起動側が処理するオプション (VM 選択オプションなど) は扱われません。
JVMTI 環境
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 仮想マシンのバイトコード命令を変更する「バイトコードインストゥルメンテーション (bytecode instrumentation)」機能をサポートします。通常、これらの変更では、メソッドのコードに「イベント」が追加されます。たとえば、メソッドの先頭に、MyProfiler.methodEntered()
の呼び出しが追加されます。変更は純粋に追加であるため、アプリケーションの状態や動作を変更する必要はありません。挿入されるエージェントコードは標準バイトコードなので、VM をフルスピードで実行できます。このため、ターゲットプログラムだけでなく、インストゥルメンテーションも最適化されます。インストゥルメンテーションにバイトコードの実行からの切り替えが含まれない場合、効率の悪い状態の切り替えは不要です。結果として、イベントのパフォーマンスは高くなります。この方 法では、エージェントを完全に制御できます。インストゥルメンテーションは、コードの「重要な」部分 (エンドユーザーのコードなど) に限定可能で、条件付きにすることができます。インストゥルメンテーションは、完全に Java プログラミング言語コード内で実行できます。または、ネイティブエージェント内で呼び出すこともできます。インストゥルメンテーションは、カウンタを保持するだけの設定にしても、イベントの統計サンプルをとる設定にしてもかまいません。
インストゥルメンテーションの挿入は、次の 3 とおりのうちのいずれかの方法で行います。
-
静的インストゥルメンテーション: クラスファイルは VM にロードする前に計測されます。このために、たとえば、インストゥルメンテーションを追加するために変更された
*.class
ファイルの重複ディレクトリを作成できます。この方法は非常に面倒です。一般に、エージェントはロードされるクラスファイルの出所を認識しません。
-
ロード時のインストゥルメンテーション: クラスファイルが VM にロードされるとき、クラスファイルの raw バイトは、インストゥルメンテーション用としてエージェントに送信されます。クラスのロードによって発生した
ClassFileLoadHook
イベントが、この機能を提供します。この方法は効率がよく、1 回限りのインストゥルメンテーションに完全にアクセスできます。
-
動的インストゥルメンテーション: すでにロードされ、場合によっては実行されていることもあるクラスを変更します。このオプション機能は、
RetransformClasses
関数の呼び出しによって発生した ClassFileLoadHook
イベントによって提供されます。クラスは何回でも変更できます。元の状態に戻すのも簡単です。この方法では、実行中のインストゥルメンテーションの変更が可能です。
このインタフェースに用意されたクラス変更機能は、インストゥルメンテーションの機構を提供し (ClassFileLoadHook
イベントと RetransformClasses
関数)、開発時には修正しながらデバックを続けていく (RedefineClasses
関数) ために用意されています。
依存関係が混乱しないように、特にコアクラスを計測する場合は、注意が必要です。たとえば、各オブジェクト割り当ての通知を受けるアプローチでは、Object
でコンストラクタを計測します。コンストラクタが最初は空であるとすると、このコンストラクタを次のように変更します。
public Object() {
MyProfiler.allocationTracker(this);
}
しかし、ClassFileLoadHook
イベントを使用してこの変更を行った場合は、通常の VM に次のような影響があります。最初に作成されたオブジェクトがコンストラクタを呼び出して、MyProfiler
のクラスがロードされます。 これによりオブジェクトが作成されますが、MyProfiler
はまだロードされていないため、無限回帰が発生してしまい、スタックオーバーフローとなります。これを変更して、安全なタイミングになるまでトラッキングメソッドの呼び出しを遅らせます。たとえば trackAllocations
を VMInit
イベントのハンドラで設定することができます。
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 仕様の 「Modified UTF-8 Strings」セクションを参照してください。
仕様のコンテキスト
このインタフェースは Java 仮想マシンで実行されるアプリケーションの状態にアクセスするため、用語は JavaTM プラットホームに関するものであり、特に言及している場合を除いてネイティブプラットホームに関するものではありません。例を示します。
- 「スレッド」は JavaTM プログラミング言語のスレッドを意味する。
- 「スタックフレーム」は Java 仮想マシンのスタックフレームを意味する。
- 「クラス」は Java プログラミング言語のクラスを意味する。
- 「ヒープ」は Java 仮想マシンのヒープを意味する。
- 「モニター」は Java プログラミング言語のオブジェクトモニターを意味する。
Sun、Sun Microsystems、Sun のロゴ、Java、および JVM は、米国ならびにその他の国における米国 Sun Microsystems, Inc. の登録商標です。
関数
JVMTI 関数のアクセス
ネイティブコードは、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
は、JVM TI 版の version
引数を必要とします。返される環境のバージョンが要求されたバージョンと異なっていても、要求されたバージョンと互換性があれば、問題はありません。JVM TI がサポートされていないか、現在の VM 構成で JVM TI がサポートされていない場合、互換バージョンが得られないと、GetEnv
は JNI_EVERSION
を返します。特定のコンテキストでは、JVM TI 環境を作成するためにその他のインタフェースを追加できます。各環境には、固有の状態があります。たとえば、必須イベント、イベント処理関数、権限などです。環境は、DisposeEnvironment
によってリリースされます。このため、スレッドごとに環境を持つ 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 Exceptions」セクションを参照してください。
関数の索引
メモリー管理
メモリー管理関数:
これらの関数は、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 では、予約ビットを 0 に設定する必要があります。エージェントは予約ビットを無視しなければなりません。予約ビットは 0 であると想定しないでください。またそのため比較には含めないでください。
例
これから説明する値は、予約ビットとベンダービットを除外しています。
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* は、サイズ *owned_monitor_depth_count_ptr の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放する必要がある。jvmtiThreadGroupInfo の 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 が設定されている。monitors_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 |
一番高い優先順位
|
新しいスレッドは、指定の優先順位
で、デーモンスレッドとして起動されます。有効な場合は、ThreadStart
イベントが送信されます。
スレッドの起動が完了しているため、このスレッドはこの関数が戻る際にライブ状態になっています。ただし、このスレッドがすぐに終了した場合は除きます。
このスレッドのスレッドグループは無視されます。具体的には、このスレッドは、スレッドグループに追加されず、Java プログラミング言語、JVM TI のいずれのレベルでもスレッドグループのクエリーには表示されません。
このスレッドは、Java プログラミング言語のクエリーでは表示されませんが、GetAllThreads
や GetAllStackTraces
など、JVM TI のクエリーには含まれます。
proc
の実行時に、新しいスレッドは VM に接続されます。JNI のマニュアルの「Attaching to the VM」を参照してください。
名前
|
型
|
説明
|
thread | jthread |
実行するスレッド。
|
proc | jvmtiStartFunction |
起動関数
|
arg | const void
* |
起動関数の引数。
エージェントがポインタを渡す。arg が NULL の場合、起動関数に NULL が渡される。
|
priority | jint |
開始されるスレッドの優先順位。java.lang.Thread.setPriority で許可されているスレッド優先順位を使用できる (jvmtiThreadPriority の優先順位を含む)。
|
スレッドローカルな記憶領域の設定
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 仮想マシン仕様』の「Frames」セクションに記載されています。つまり、これらのフレームは、ネイティブメソッドを含むメソッドの呼び出しに対応しているが、プラットフォーム固有のフレームや 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);
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 仮想マシン仕様』の用語で説明すると、次のようになります。
- 現在のフレームが破棄され、以前のフレームが現在のフレームになる
- オペランドスタックが回復する。引数の値が再度追加され、呼び出しが
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 仮想マシン仕様』の「Frames」セクションに定義されているとおり、関数の呼び出し時に、指定されたスレッドの現在のメソッドになります。
指定されたスレッドは、中断されているか、現在のスレッドでなければいけません。メソッドの復帰は、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 の場合、現在のスレッドが使用される。
|
ヒープ
ヒープ関数:
ヒープの関数型:
ヒープの型:
ヒープのフラグおよび定数:
これらの関数は、ヒープの分析に使用されます。ヒープ内のオブジェクトの表示、これらのオブジェクトへのタグ付けなどの機能があります。
「タグ」は、オブジェクトに関連付けられる値です。タグは、エージェントにより、タグの設定
関数を使って明示的に設定されます。または、jvmtiHeapIterationCallback
などのコールバック関数によって設定されます。
タグは環境に対してローカルです。つまり、ある環境のタグを別の環境で表示することはできません。
タグは jlong
値です。この値を使って、オブジェクトにマークを付けたり、詳細情報のポインタを格納したりできます。タグ付けされていないオブジェクトには、ゼロのタグが付いています。タグをゼロに設定することにより、オブジェクトのタグ付けを解除できます。
ヒープコールバック関数
ヒープ関数は、ヒープ内での繰り返し処理とオブジェクト参照の再帰的な追跡を行い、エージェントが指定したコールバック関数を使って情報提供を行います。
これらのヒープコールバック関数は、次の制限に従います。これらのコールバックで JNI 関数は使用しないでください。これらのコールバックでは、特別に使用が許可されている「コールバック安全」な関数以外の JVM TI 関数を使用できません (raw モニター関数、メモリー管理関数、環境ローカル記憶領域関数を参照)。
実装は、内部スレッド上または繰り返し関数を呼び出したスレッド上で、コールバックを呼び出すことができます。ヒープコールバックはシングルスレッドです。複数のコールバックが同時に呼び出されることはありません。
ヒープフィルタフラグを使うと、オブジェクトまたはそのクラスのタグの状態に基づいて報告を行わないようにすることができます。フラグが設定されていない場合 (jint
がゼロの場合)、オブジェクトのフィルタリングは行われません。
定数
|
値
|
説明
|
JVMTI_HEAP_FILTER_TAGGED | 0x4 |
タグ付きのオブジェクトをフィルタリングする。タグの付いたオブジェクトが除外される。
|
JVMTI_HEAP_FILTER_UNTAGGED | 0x8 |
タグなしのオブジェクトをフィルタリングする。タグの付いていないオブジェクトが除外される。
|
JVMTI_HEAP_FILTER_CLASS_TAGGED | 0x10 |
タグ付きのクラスを持つオブジェクトをフィルタリングする。タグの付いたクラスのオブジェクトが除外される。
|
JVMTI_HEAP_FILTER_CLASS_UNTAGGED | 0x2; |
タグなしのクラスを持つオブジェクトをフィルタリングする。タグの付いていないクラスのオブジェクトが除外される。
|
ヒープコールバックによって返されるヒープビジット制御フラグを使うと、繰り返し処理を中止できます。また、ヒープ参照コールバックは、トラバース対象となる参照のグラフを取り除くために使うこともできます (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;
局所変数参照用の参照情報構造体
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
は、ビジットされるオブジェクトは制御しませんが、コールバックによって報告されるオブジェクトおよびプリミティブ値は制御します。たとえば、設定された唯一のコールバックが配列プリミティブ値コールバック
であり、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
は、ビジットされるオブジェクトは制御しませんが、コールバックによって報告されるオブジェクトおよびプリミティブ値は制御します。たとえば、設定された唯一のコールバックが配列プリミティブ値コールバック
であり、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 仮想マシン仕様』の「Constant Pool」セクションを参照。
|
定数
|
値
|
説明
|
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 回だけ呼び出されます。参照サイクルや、参照側のパスが複数存在する場合も同様です。参照側と参照される側の間に、複数の参照が存在する場合があります。これらの識別には、jvmtiObjectReference.reference_ (種類)
と jvmtiObjectReference.referrer_ (インデックス)
を使用します。オブジェクトのコールバックは、常に参照側のコールバックのあとで行われます。
報告されるオブジェクト参照については、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_root_callback
が 呼び出されます。オブジェクトは、1 つ以上の理由でルートオブジェクトになることができます。この場合、個々の理由に対して適切なコールバックが呼び出されます。
各オブジェクト参照に、object_ref_callback
関数が呼び出され、オブジェクト参照について説明します。コールバックは、参照側からの参照のたびに 1 回だけ呼び出されます。参照サイクルや、参照側のパスが複数存在する場合も同様です。参照側と参照される側の間に、複数の参照が存在する場合があります。これらの識別には、jvmtiObjectReference.reference_ (種類)
と jvmtiObjectReference.referrer_ (インデックス)
を使用します。オブジェクトのコールバックは、常に参照側のコールバックのあとで行われます。
報告されるオブジェクト参照については、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
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 仮想マシン仕様』の「Creation and Loading」セクションを参照してください。
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 仮想マシン仕様』の「Class File Format」の章で定義されています。
クラスが配列クラスの場合、その 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 仮想マシン仕様』の「Class File Format」の章で定義されているように、マイナーバージョン番号とメジャーバージョン番号を返します。
名前
|
型
|
説明
|
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 仮想マシン仕様』の「Class File Format」に記載された 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
で) 戻った場合、再定義対象のすべてのクラスに新しい定義がインストールされます。
名前
|
型
|
説明
|
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 を 1 回呼び出す間に変更されることがあります。
名前
|
型
|
説明
|
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 仮想マシン仕様』ではフィールド記述子と呼ばれています。
名前
|
型
|
説明
|
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 仮想マシン仕様』の「Class File Format」の章で定義されています。
名前
|
型
|
説明
|
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 は新しいメソッドバージョンを参照するようになります。廃棄されたメソッドかどうかをテストするには、IsMethodObsolete
を使用します。
メソッドの名前とシグニチャーの取得
jvmtiError
GetMethodName(jvmtiEnv* env,
jmethodID method,
char** name_ptr,
char** signature_ptr,
char** generic_ptr)
method
で指定されたメソッドの名前を name_ptr
を介して返し、メソッドのシグニチャーを signature_ptr
を介して返します。
メソッドのシグニチャーは JNI 仕様で定義されており、『Java 仮想マシン仕様』ではメソッド記述子と呼ばれています。『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 仮想マシン仕様』の「Class File Format」の章で定義されています。
名前
|
型
|
説明
|
method | jmethodID |
照会するメソッド。
|
modifiers_ptr | jint* |
戻ったとき、アクセスフラグをポイントする。
エージェントは jint にポインタを渡す。戻ったとき、jint が設定されている。 |
局所変数の取得
jvmtiError
GetMaxLocals(jvmtiEnv* env,
jmethodID method,
jint* max_ptr)
method
で指定されたメソッドによって使用される局所変数 (呼び出し時にメソッドにパラメータを渡すために使用される局所変数を含む) のスロット数を返します。
『Java 仮想マシン仕様』の「Code Attribute」セクションの 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 仮想マシン仕様』の「Field Descriptors」セクションで定義された形式と同じになる。
|
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)
capabilities_ptr
を介して、現時点でこの環境が所有できる JVM TI 機能を返します。返される機能が、VM が実装する完全な権限セットとは異なる場合があります。該当するのは、別の環境が、複数の環境による所有を許可されていない権限を所有している場合、そして現在の段階がライブ段階で、特定の権限は 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 仮想マシン仕様』の「Loading Using the Bootstrap Class Loader」を参照してください。ブートストラップクラスローダーがクラスの検索に失敗したあと、指定されたプラットフォーム依存の検索パスセグメント
を検索します。segment
に指定できるセグメントは、1 つだけです。複数のセグメントを追加する場合、この関数を複数回呼び出すことができます。 セグメントは、この関数が呼び出された順に検索されます。
OnLoad
段階でこの関数を使うと、ブートストラップクラスローダーがクラスの検索に失敗した際に、追加で検索する任意のプラットフォーム依存の検索パスセグメントを指定できます。このセグメントは通常、ディレクトリと JAR ファイルのいずれかになります。
ライブ段階で segment
を使うと、任意のプラットフォーム依存の JAR ファイルへのパスを指定できます。ブートストラップクラスローダーがインストゥルメンテーション目的で定義するクラスやリソース以外のものが JAR ファイルに含まれないように、エージェントで確認するようにしてください。
『Java 仮想マシン仕様』によると、Java 仮想マシンが以前にシンボリック参照を解決しようとして失敗した場合、その後このシンボリック参照を解決しようとしても必ず失敗し、最初に解決しようとした結果としてスローされたエラーと同じエラーになります。したがって、Java 仮想マシンが参照を解決できなかったクラスに対応するエントリが JAR ファイルに含まれる場合、その参照を解決しようとしても最初のエラーと同じエラーで失敗します。
名前
|
型
|
説明
|
segment | const char* |
プラットフォーム依存の検索パスセグメント。修正 UTF-8 文字列としてエンコードされる。
エージェントは、char の配列を渡す。 |
システムクラスローダー検索の追加
jvmtiError
AddToSystemClassLoaderSearch(jvmtiEnv* env,
const char* segment)
この関数では、システムクラスローダーを使ってインストゥルメンテーションクラスを定義できます。『Java 仮想マシン仕様』の「Loading Using a User-defined Class Loader」を参照してください。クラスローダーがクラスの検索に失敗したあと、指定されたプラットフォーム依存の検索パスセグメント
を検索します。segment
に指定できるセグメントは、1 つだけです。複数のセグメントを追加する場合、この関数を複数回呼び出すことができます。 セグメントは、この関数が呼び出された順に検索されます。
OnLoad
段階でこの関数を使うと、システムクラスローダーがクラスの検索に失敗した際に、追加で検索する任意のプラットフォーム依存の検索パスセグメントを指定できます。このセグメントは通常、ディレクトリと JAR ファイルのいずれかになります。
ライブ段階では、segment
は、システムクラスローダーがクラスの検索に失敗した際に、追加で検索するプラットフォーム依存の JAR ファイルへのパスになります。システムクラスローダーがインストゥルメンテーション目的で定義するクラスやリソース以外のものが JAR ファイルに含まれないように、エージェントで確認するようにしてください。
ライブ段階でシステムクラスローダーが検索対象 JAR ファイルの追加をサポートするのは、java.lang.String
型の単一パラメータを取る appendToClassPathForInstrumentation
という名前のメソッドをシステムクラスローダーが実装している場合です。このメソッドは、public
アクセスを備えていなくてもかまいません。
『Java 仮想マシン仕様』によると、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)
VM システムプロパティーの値を設定します。
関数 GetSystemProperties
は、プロパティーキーのセットを返します。そのうちのいくつかは設定可能です。GetSystemProperty
を参照してください。
名前
|
型
|
説明
|
property | const char* |
プロパティーのキー。修正 UTF-8 文字列としてエンコードされる。
エージェントは、char の配列を渡す。 |
value | const char
* |
設定するプロパティー値。修正 UTF-8 文字列としてエンコードされる。
エージェントは、char の配列を渡す。value が 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 関数内。
|
JVMTI_PHASE_PRIMORDIAL | 2 |
初期段階:Agent_OnLoad が返されてから 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 ビット。
|
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);
|
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);
|
イベント
イベントの処理
エージェントは、アプリケーションプログラム内で発生する多くのイベントについての通知を受けることができます。
イベントを処理するには、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 つのイベントについては、レポートされる順序は特に指定されていません。
同じ位置で発生するイベントは、同じスレッド内の同じ位置でのエージェントによる処理中にトリガーされることがあります。その種のイベント (タイプ y) が、タイプ x のイベントの処理中にトリガーされたとしましょう。前述の説明にある順序によると 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 仮想マシン仕様』に定義されているように、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 言語仕様』の「Loading of Classes and Interfaces」を参照してください。ほとんどの場合、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 リソースは作成されません。関数 (たとえば ROMized classes) との互換性がないクラスについては、このイベントは生成されません。
エージェントは、メモリー割り当て関数 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" など)。修正 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 初期化イベントのハンドラが復帰するまでは発生しないことが保証されています。
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 によって送信され、エージェントにデータをダンプするよう要求します。これは単に示唆しているだけであり、エージェントはこのイベントに必ずしも反応する必要はありません。これは、ユーザーからのコマンド行シグナルを処理する場合に便利です。たとえば、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 がまだ停止している間に送信されるので、イベントハンドラは、特別に使用が許可されている JVM TI 関数以外の関数および JNI 関数を使用できません (raw モニター関数、メモリー管理関数、環境ローカル記憶領域関数を参照)。
このイベントは、常に GarbageCollectionFinish
と一致するペア (どちらのイベントも有効とみなされる) として送信され、これらの間に、ガベージコレクションイベントは発生しません。
ガベージコレクションの完了
void JNICALL
GarbageCollectionFinish(jvmtiEnv *jvmti_env)
ガベージコレクションの終了イベントは、ガベージコレクションの全サイクルが終了したとき送信されます。このイベントは、VM がまだ停止している間に送信されるので、イベントハンドラは、特別に使用が許可されている JVM TI 関数以外の関数および JNI 関数を使用できません (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
変更履歴
最終更新日:06/08/06 22:33:32
ファイルのバージョン:@(#)jvmti.xml 1.202
バージョン: 1.1.102
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 から正確でない記述を削除 (http://java.sun.com/docs/books/vmspec/2nd-edition/html/ConstantPool.doc.html#79383 を参照)
|
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 イベントを追加
|