JavaTM Virtual Machine Tool
Interface
Reference Draft 0.30.27
|
JVMTI とは
JavaTM Virtual Machine Tool
Interface (JVMTI) は、開発ツールや監視ツールで使用されるプログラミングインタフェースです。JVMTI は、JavaTM 仮想マシン (VM)
で動作するアプリケーションの状態検査と実行制御の両方の機能を提供し、
プロファイリングツール、デバッグツール、監視ツール、スレッド分析ツール、カバレッジ分析ツールなど、VM
の状態その他にアクセスする必要がある各種ツールの VM インタフェースとして機能します。
JVMTI は、Java 仮想マシンのすべての実装で使用できるとは限りません。
JVMTI は、双方向のインタフェースです。以下では、JVMTI のクライアントを「エージェント」と呼びます。エージェントは、イベントから、さまざまな状態の発生通知を受け取ることができます。JVMTI
は、イベントに応答して、またはイベントからは独立して、多くの関数を使ってアプリケー
ションへの照会および制御を実行できます。
個々のエージェントは同一のプロセスで実行され、検査対象のアプリケーションを実行する仮想マシンと直接通信します。この通信には、ネイティブインタ
フェース (JVMTI)
が使用されます。ネイティブのインプロセスインタフェースにより、ツール側への侵入は最小限に抑えながら、最大限の制御が可能になります。通常、エージェ
ントは比較的コンパクトです。エージェントは、ターゲットアプリケーションの通常の実行を妨げることなく、ツールの機能の大部分を実装する別のプロセスに
よって制御できます。
アーキテクチャ
ツールへの書き込みは、JVMTI を使って直接行われるか、Java
プラットフォームツールアーキテクチャの高度インタフェースを使って間接的に行われます。Java
プラットフォームツールアーキテクチャは、高度なアウトプロセスデバッガインタフェースを持つ Java
プラットフォームデバッガアーキテクチャの拡張版です。多くのツールには、JVMTI よりも高いレベルのインタフェースの方が適しています。Java
プラットフォームデバッガアーキテクチャの詳細については、Java
プラットフォームデバッガアーキテクチャの Web サイトを参照してください。
エージェントの作成
エージェントの作成には、各種規則と C/C++ の定義を呼び出す C 言語をサポートする任意のネイティブ言語を使用できます。
JVMTI を使用するために必要な関数、イベント、データ型、定数の定義は、インクルードファイル jvmti.h
で定義されます。これらの定義を使用するには、J2SETM
インクルードディレクトリをインクルードパスに追加し、ソースコードに次の行を追加します。
#include <jvmti.h>
JVMTI エージェントのコマンド行オプション
以下の「コマンド行オプション」という語は、JNI 呼び出し API の JNI_CreateJavaVM
関数において、JavaVMInitArgs
引数で指定されるオプションを意味します。
エージェントを適切にロードして実行するには、VM
の起動時に次のいずれかのコマンド行オプションが必要です。これらの引数は、エージェントを含むライブラリと、起動時に渡されるオプションの文字列を指定
します。
-agentlib:
<agent-lib-name>=
<options>
-
-agentlib:
の後ろには、ロードするライブラリの名前を指定します。ライブラリのフルネームと場所の検索方法は、プラットフォームによって異なります。通常、<agent-lib-name>
は、オペレーティングシステム固有のファイル名に展開されます。<options>
は、起動時にエージェントに渡されます。たとえば、オプション -agentlib:foo=opt1,opt2
が指定された場合、VM は、WindowsTM ではシステムパス PATH
から共用ライブラリ foo.dll
をロードしようとします。SolarisTM
環境では、LD_LIBRARY_PATH
から libfoo.so
をロードしようとします。
-agentpath:
<path-to-agent>=
<options>
-
-agentpath:
の後ろには、ライブラリをロードする絶対パスを指定します。ライブラリ名の展開は行われません。<options>
は、起動時にエージェントに渡されます。たとえば、オプション -agentpath:c:\myLibs\foo.dll=opt1,opt2
が指定された場合、VM は、共用ライブラリ c:\myLibs\foo.dll
をロードしようとします。
ライブラリ内の起動ルーチン Agent_OnLoad が呼び出されます。
バイトコードインストゥルメンテーション (bytecode instrumentation)
のために必要な場合、ツール内で Java プログラミング言語コードを使用しやすくするため、-agentlib:
または -agentpath:
を指定してロードされたライブラリから、JNI
ネイティブメソッド実装が検索されます。
エージェントライブラリは、その他のすべてのライブラリが検索されたあと検索されます。非エージェントメソッドのネイティブメソッド実装を上書きまたは遮
断するエージェントは、NativeMethodBind イベントを使用できます。
これらのスイッチは、上記の処理だけを行います。VM や JVMTI の状態を変更することはありません。JVMTI や JVMTI
の一部を有効にする処理は、権限 (capability) により、プログラムを通して行われ
ます。コマンド行オプションは必要ありません。.
エージェントの起動
ライブラリは、次のプロトタイプを持つ起動関数をエクスポートしている必要があります。
JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
この関数は、ライブラリのロード時に VM によって呼び出されます。VM は、VM の初期化の早い段階でライブラリをロードする必要があります。
- システムプロパティは、VM の起動で使用される前に設定できる
- すべての権限を使用できる (ただし、VM
を構成する権限はこのときしか使用できない。詳細は権限関数の節を参照)
- バイトコードが実行されていない
- クラスがロードされていない
- オブジェクトが作成されていない
VM は、2 番目の引数として <options> を指定して Agent_OnLoad
関数を呼び出します。つまり、コマンド行オプションの例を使用して、"opt1,opt2"
は Agent_OnLoad
の char *options
引数に渡されます。=<options>
が指定されていない場合、options
には長さ 0 の文字列が渡されます。options
文字列は、Agent_OnLoad
呼び出しの間有効です。必要な場合は、この期間が過ぎても、文字列または文字列の一部をコピーする必要があります。Agent_OnLoad
が呼び出されてから終了するまでの期間を「ロード段階」と呼びます。VM はロード段階では初期化され
ません。このため、Agent_OnLoad
内部で許可された操作は限定されています
(この時点で使用可能な機能については関数の説明を参照)。エージェントが安全に実行できるのは、オプションの処理や、SetEventCallbacks
を使ってイベントコールバックを設定する処理です。VM 初期化イベントを受け取ってから (つまり、VMInit
コールバックが呼び出されてから)、エージェントは初期化を完了できます。
原理の説明:
早い段階での起動が必要なのは、エージェントが必要な権限を設定できるようにするためです。多くの権限は、VM
の初期化前に設定する必要があります。JVMDI では、-Xdebug
コマンド行オプションで権限を制御できます。ただし、この制御は非常におおまかなものです。JVMPI
実装は、さまざまなテクニックを使って単一の「JVMPI
オン」スイッチを提供します。必要な権限とパフォーマンスへの影響のバランスをとるために必要な細かい制御を提供するのに適したコマンド行オプションはあ
りません。早い段階での起動には、エージェントが各種機能をインストールするため、ファイルシステムやシステムプロパティに変更を加え、実行環境を制御で
きるようにする目的もあります。
Agent_OnLoad
の戻り値は、エラーを示すために使用されます。ゼロ以外の値はエラーを表します。エラーが発生すると、VM は終了します。
エージェントの停止
ライブラリは、オプションで、次のプロトタイプを持つ停止関数をエクスポートできます。
JNIEXPORT void JNICALL
Agent_OnUnload(JavaVM *vm)
この関数は、ライブラリのアンロードの直前に VM
によって呼び出されます。プラットフォーム固有の機構に問題がある場合、アンロードが引き起こされ、この関数が呼び出されます
(本書ではアンロード機構は指定しない)。正常な処理もしくは VM の障害 (起動時の障害を含む) によって VM
が終了した場合、ライブラリは実際にアンロードされます。もちろん、制御できない停止は、この規則に当てはまりません。この関数と VM Death イベントには違いがあります。VM Death
イベントを送信するためには、初期化の前に VM を実行したことがあり、VMDeath のコールバックを設定した有効な JVMTI
環境が存在し、イベントが有効になっている必要があります。これらの条件は、Agent_OnUnload
には不要です。この関数は、ライブラリがその他の理由によってアンロードされたときも呼び出されます。VM Death
イベントは、この関数が呼び出される前に送信されます (この関数が VM の終了によって呼び出される場合)。この関数を使って、Agent_OnLoad
時に割り当てられたリソースをクリーンアップすることができます。
JAVA_TOOL_OPTIONS
コマンド行は常にアクセスまたは変更できるとは限らないため、たとえばインストゥルメンテーション 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 環境
JVMTI 仕様は、同時に複数の JVMTI エージェントを使用することを許可します。各エージェントには固有の JVMTI
環境が割り当てられます。つまり、JVMTI
の状態はエージェントごとに異なっています。ある環境に変更を加えても、その他の環境に影響はありません。JVMTI 環境には、次の状態があります。
JVMTI の状態は独立していますが、エージェントは VM
の共有の状態を検査し、変更します。また、エージェントが実行されるネイティブ環境を共有します。このため、あるエージェントがその他のエージェントの実
行結果に影響を及ぼしたり、その他のエージェントの失敗の原因になることがあります。エージェントの作成者には、このエージェントとその他のエージェント
との互換性のレベルを指定する責任があります。JVMTI
実装は、エージェント間の悪影響を防ぐことはできません。これらの問題の発生を防ぐ技術については、本書では説明しません。
エージェントは、JNI 呼び出し API 関数 GetEnv
にインタフェース ID として JVMTI のバージョン情報を渡すことによって、JVMTI 環境を作成します。JVMTI
環境の作成と使用の詳細については、「JVMTI 関数のアクセス」を参照してください。通常、
JVMTI 環境は、Agent_OnLoad から GetEnv
を呼び出すことによって作成されます。
バイトコードインストゥルメンテーション
このインタフェースは、プロファイリングをサポートするインタフェースで発生するイベントの一部を含みません。該当するイベントとして、オブジェクト割り
当てイベントやフルスピードメソッド入力/出力イベントがあります。このインタフェースは、ターゲットプログラムを構成する Java
仮想マシンのバイトコード命令を変更する「バイトコードインストゥルメンテーション (bytecode
instrumentation)」機能をサポートします。通常、これらの変更では、メソッドのコードに「イベント」が追加されます。たとえば、メソッド
の先頭に、MyProfiler.methodEntered()
の呼び出しが追加されます。変更は純粋に追加であるため、アプリケーションの状態や動作を変更する必要はありません。挿入されるエージェントコードは標準
バイトコードなので、VM
をフルスピードで実行できます。このため、ターゲットプログラムだけでなく、インストゥルメンテーションも最適化されます。インストゥルメンテーションに
バイトコードの実行からの切り替えが含まれない場合、効率の悪い状態の切り替えは不要です。結果として、イベントのパフォーマンスは高くなります。この方
法では、エージェントを完全に制御できます。インストゥルメンテーションは、コードの「重要な」部分 (エンドユーザのコードなど)
に限定可能で、条件付きにすることができます。インストゥルメンテーションは、完全に Java
プログラミング言語コード内で実行できます。または、ネイティブエージェント内で呼び出すこともできます。インストゥルメンテーションは、カウンタを保持
するだけの設定にしても、イベントの統計サンプルをとる設定にしてもかまいません。
インストゥルメンテーションの挿入は、次の 3 通りのうちのいずれかの方法で行います。
- 静的インストゥルメンテーション:クラスファイルは VM
にロードする前に実装されます。このために、たとえば、インストゥルメンテーションを追加するために変更された
*.class
ファイルの重複ディレクトリを作成できます。この方法は非常に面倒です。一般に、エージェントはロードされるクラスファイルの出所を認識しません。
- ロード時のインストゥルメンテーション:クラスファイルが VM にロードされるとき、クラスファイルの raw
バイトは、インストゥルメンテーション用としてエージェントに送信されます。この機能は、ク
ラスファイルロードフックイベントによって提供されます。この方法は効率がよく、1
回限りのインストゥルメンテーションに完全にアクセスできます。
- 動的インストゥルメンテーション:すでにロードされ、場合によっては実行されていることもあるクラスを変更します。このオプション機能は、
RedefineClasses
関数によって提供されます。クラスは何回でも変更できます。元の状態に戻すのも簡単です。この方法では、実行中のインストゥルメンテーションの変更が可能
です。
このインタフェースに用意されたクラス変更機能 (Class File Load
Hook および RedefineClasses
)
は、インストゥルメンテーションの機構を提供し (前述)、開発時には修正しながらデバックを続けていくために用意されています。
依存関係が混乱しないように、特にコアクラスをインストルメントする場合は、注意が必要です。たとえば、各オブジェクト割り当ての通知を受けるアプローチ
では、Object
にコンストラクタをインストルメントします。コンストラクタが最初は空であるとすると、このコンストラクタを次のように変更します。
public Object() {
MyProfiler.allocationTracker(this);
}
しかし、Class File Load Hook
イベントを使用してこの変更を行った場合は、通常の VM に次のような影響があります。最初に作成されたオブジェクトがコンストラクタを呼び出して、MyProfiler
のクラスがロードされます。これによりオブジェクトが作成されますが、MyProfiler
はまだロードされていないため、無限回帰が発生してしまい、スタックオーバーフローとなります。これを変更して、安全なタイミングになるまでトラッキング
メソッドの呼び出しを遅らせます。たとえば trackAllocations
を VMInit
イベントのハンドラで設定することができます。
static boolean trackAllocations = false;
public Object() {
if (trackAllocations) {
MyProfiler.allocationTracker(this);
}
}
仕様のコンテキスト
このインタフェースは Java 仮想マシンで実行されるアプリケーションの状態にアクセスするため、用語は JavaTM
プラットホームに関するものであり、特に言及している場合を除いてネイティブプラットホームに関するものではありません。例を示します。
- 「スレッド」は JavaTM
プログラミング言語のスレッドを意味する
- 「スタックフレーム」は Java 仮想マシンのスタックフレームを意味する
- 「クラス」は Java プログラミング言語のクラスを意味する
- 「ヒープ」は Java 仮想マシンのヒープを意味する
- 「モニター」は Java プログラミング言語のオブジェクトモニターを意味する
関数
JVMTI 関数のアクセス
ネイティブコードは、JVMT 関数を呼び出して JVMTI 機能にアクセスします。JVMTI 関数には、Java Native Interface (JNI) 関数のアクセス時と同様に、インタフェースポインタを使ってアクセスします。JVMTI
インタフェースポインタを「環境ポインタ」と呼びます。
環境ポインタは、jvmtiEnv*
型の環境へのポインタです。環境には、JVMTI
接続に関する情報があります。環境内の最初の値は、関数テーブルへのポインタです。関数テーブルは、JVMTI
関数へのポインタの配列です。どの関数ポインタも配列内の事前に定義されたオフセットにあります。このため、関数のアクセスには、二重間接指定が使用され
ます。環境ポインタは、コンテキストを提供する、各関数の最初のパラメータです。例を示します。
jvmtiEnv *jvmti;
...
jvmtiError err = (*jvmti)->GetLoadedClasses(jvmti, &class_count, &classes);
JVMTI 環境は、JNI 呼び出し API の GetEnv
関数を使って取得できます。
jvmtiEnv *jvmti;
...
(*jvm)->GetEnv(jvm, &jvmti, JVMTI_VERSION_1_0);
GetEnv
を呼び出すたびに、新しい JVMTI 接続が作成され、新しい JVMTI 環境が作成されます。GetEnv
は、JVMTI 版の version
引数を必要とします。返される環境のバージョンが要求されたバージョンと異なっていても、要求されたバージョンと互換性があれば、問題はありません。
JVMTI がサポートされていないか、現在の VM 構成で JVMTI がサポートされていない場合、互換バージョンが得られないと、GetEnv
は JNI_EVERSION
を返します。特定のコンテキストでは、JVMTI
環境を作成するためにその他のインタフェースを追加できます。各環境には、固有の状態があります。たとえば、必須イベント、イベント処理関数、権限な
どです。環境は、DisposeEnvironment
によってリリースされます。このため、スレッドごとに環境を持つ JNI とは異なり、JVMTI
環境は動的に作成され、複数のスレッドにまたがって機能します。
関数の戻り値
JVMTI 関数は、常に jvmtiError
関数の戻り値からエラーコードを返します。関数によっては、呼び出し側の関数で指定されたポイ
ンタにより、これ以外の値を返すことも可能です。JVMTI
の関数の中にはメモリを割り当てるものがありますが、この場合はプログラム内でそのメモリを明示的に解放しなければなりません。これについては、個々の関
数の説明に明記されています。空のリスト、配列、シーケンスなどは、NULL
として返されます。
JVMTI 関数がエラーに遭遇した場合は (戻り値が JVMTI_ERROR_NONE
以外)、引数ポインタにより参照されるメモリ値は未定義です。しかし、メモリおよびグローバル参照は何も割り当てられません。無効な入力によってエラーが
発生した場合、アクションは発生しません。
JNI オブジェクト参照の管理
JVMTI 関数は、JNI 参照 (jobject
と jclass
) とその派生 (jthread
と jthreadGroup
)
によってオブジェクトを識別します。JVMTI
の関数に渡される参照は、グローバルでもローカルでもかまいませんが、強い参照でなければなりません。JVMTI
関数から返されるすべての参照は、ローカル参照です。これらのローカル参照は、JVMTI
の呼び出し時に作成されます。ローカル参照は、管理対象にするべきリソースです (JNI Documentation
を参照)。スレッドがネイティブコードから返される場合、すべてのローカル参照は解放されます。典型的なエージェントスレッドを含む一部のスレッドは、決
してネイティブコードからは返されません。各スレッドは、明示的管理なしで 16
個のローカル参照を作成することができます。ネイティブコードから返される前に、限定された数の JVMTI 呼び出しを実行するスレッド
(イベント処理スレッドなど)
の場合、明示的管理は不要であると判断されます。しかし、長時間実行されるエージェントスレッドは、明示的ローカル参照管理を必要とします。通常、この管
理には、JNI 関数 PushLocalFrame
と PopLocalFrame
を使用します。逆に言えば、ネイティブコードから返されたあとも参照を保存したい場合は、グローバル参照に変換する必要があります。
関数呼び出しの必要条件
関数に、スレッドまたは VM を特定の状態 (中断など)
にするのはエージェントであると明示的に指定されていないかぎり、関数を実行するために VM を一定の安全な状態にするのは、JVMTI
実装になります。
関数の索引
メモリ管理
メモリ管理関数:
Allocate
jvmtiError Allocate(jvmtiEnv* env, jlong size, unsigned char** mem_ptr)
JVMTI のアロケータを使用して、メモリの領域を割り当てます。割り当てられたメモリは、Deallocate
によって解放してください。
この関数は、 どの段階でも呼び出し可能です。
この関数は、ヒープ繰り返し関数のコールバックから呼び出せます。GarbageCollectionStart
イベント、GarbageCollectionFinish
イベント、ObjectFree
イベントのイベントハンドラからの呼び出しも可能です。
パラメータ |
名前 |
型 |
説明 |
size |
jlong |
割り当てるバイト数
原理の説明: jlong は JVMDI
との互換性を実現するために使用される |
mem_ptr |
unsigned char** |
戻ったとき、割り当てられたメモリの先頭を指すポインタ。size がゼロの場合、NULL
が返される
エージェントは unsigned char* にポインタを渡す。戻ったとき、unsigned char*
は、サイズ size の新しく割り当てられた配列をポイントする。この配列は、Deallocate を使って解放する必要がある |
|
Deallocate
jvmtiError Deallocate(jvmtiEnv* env, unsigned char* mem)
JVMTI のアロケータを使用して、mem を解放します。この関数は、JVMTI
の関数によって割り当てられて返されたメモリ (Allocate
を使用して割り当てられたメモリを含む)
を解放するために使用します。割り当てられたすべてのメモリを解除するまで、メモリを再生することはできません。
この関数は、 どの段階でも呼び出し可能です。
この関数は、ヒープ繰り返し関数のコールバックから呼び出せます。GarbageCollectionStart
イベント、GarbageCollectionFinish
イベント、ObjectFree
イベントのイベントハンドラからの呼び出しも可能です。
パラメータ |
名前 |
型 |
説明 |
mem |
unsigned char * |
割り当てられたメモリの先頭を指すポインタ。[On return, the elements are set]
は無視してよい
エージェントは unsigned char
に配列を渡す。配列の要素の値は無視される。戻ったとき、要素が設定されているmem が NULL
の場合、呼び出しは無視される
|
|
スレッド
スレッド関数:
スレッド関数の型:
スレッドの型:
スレッド状態の取得
jvmtiError GetThreadState(jvmtiEnv* env, jthread thread, jint* thread_state_ptr)
スレッドの状態を取得します。スレッドの状態は、以下の一連の質問に答えることでわかります。
答えは次のビットベクトルで表されます。
次の定義は、JVMTI スレッド状態を java.lang.Thread.State
形式の状態に変換するために使用します。
規則
疑問に対する回答は 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, &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, &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"; }
この関数は、 ライブ段階でしか呼び出せません。
|
すべてのスレッドの取得
jvmtiError GetAllThreads(jvmtiEnv* env, jint* threads_count_ptr, jthread** threads_ptr)
すべてのライブスレッドを取得します。スレッドは、Java プログラミング言語のスレッド、つまり VM
に接続されたスレッドです。スレッドがライブスレッドなら、java.lang.Thread.isAlive()
の戻り値は true
になります。この場合、スレッドは、起動されたあと、まだ終了していません。スレッドの領域は、JVMTI
環境のコンテキストによって決定されます。通常、VM に接続されたすべてのスレッドが対象になります。
この関数は、 ライブ段階でしか呼び出せません。
パラメータ |
名前 |
型 |
説明 |
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
配列内に返されます。現在中断しているスレッドは、中断されません。
この関数は、 ライブ段階でしか呼び出せません。
|
スレッドの再開
jvmtiError ResumeThread(jvmtiEnv* env, jthread thread)
中断されているスレッドの実行を再開します。現在 JVMTI 中断関数 (SuspendThread
など) または java.lang.Thread.suspend()
によって中断されているスレッドの実行を再開します。その他のスレッドには影響はありません。
この関数は、 ライブ段階でしか呼び出せません。
|
スレッドリストの再開
jvmtiError ResumeThreadList(jvmtiEnv* env, jint request_count, const jthread* request_list, jvmtiError* results)
request_list
配列に指定されたスレッド request_count
を再開します。JVMTI 中断関数 (SuspendThreadList
など) または java.lang.Thread.suspend()
によって中断されているスレッドの実行を再開します。
この関数は、 ライブ段階でしか呼び出せません。
|
スレッドの停止
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)
指定されたスレッドが所有するモニターについての情報を取得します。
この関数は、 ライブ段階でしか呼び出せません。
|
現在競合しているモニターの取得
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
呼び出しによって作成できますが、デバッグ中のアプリケーションとの相互作用を避けるため、そのような Java
コードへの呼び出しはエージェントの初期化中に行うことをお勧めします。
次のスレッドの優先順位を使用します。
新しいスレッドは、指定の優先順位 で、デー
モンスレッドとして起動されます。有効な場合は、ThreadStart
イベントが送信されます。
proc の実行時に、新しいスレッドは VM に接続されます。JNI のマニュアルの「Attaching
to the VM」を参照してください。
この関数は、 ライブ段階でしか呼び出せません。
|
スレッドローカルな記憶領域の設定
jvmtiError SetThreadLocalStorage(jvmtiEnv* env, jthread thread, const void* data)
VM
は、個々の環境スレッドペアに関連付けられたポインタ値を格納します。このポインタ値を「スレッドローカルな記憶領域」と呼びます。この関数で設定されな
い場合、値は NULL
になります。エージェントは、スレッド固有の情報を格納するため、メモリを割り当てることができます。スレッドローカルな記憶領域を設定することにより、GetThreadLocalStorage
を使ってアクセスできるようになります。
この関数は、JVMTI のスレッドローカルな記憶領域の値を設定するため、エージェントによって呼び出されます。JVMTI
は、エージェントに対して、スレッドごとの情報を記録するために利用できる、ポインタサイズのスレッドローカルな記憶領域を提供します。
この関数は、 開始またはライブ段階でしか呼び出せません。
パラメータ |
名前 |
型 |
説明 |
thread |
jthread |
このスレッドを格納する。 thread が NULL
の場合、現在のスレッドが使用される |
data |
const void * |
スレッドローカルな記憶領域に入力する値
エージェントは配列を渡す。data が NULL の場合、値は NULL
に設定される
|
|
スレッドローカルな記憶領域の取得
jvmtiError GetThreadLocalStorage(jvmtiEnv* env, jthread thread, void** data_ptr)
JVMTI のスレッドローカルな記憶領域の値を取得するため、エージェントによって呼び出されます。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
スレッドグループ
スレッドグループ関数:
スレッドグループの型:
トップレベルのスレッドグループの取得
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
構造体のフィールドに、指定されたスレッドグループの詳細が入ります。
この関数は、 ライブ段階でしか呼び出せません。
パラメータ |
名前 |
型 |
説明 |
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 Virtual Machine Specification』の Section
3.6 Frames
の説明のとおりです。つまり、これらのフレームは、ネイティブメソッドを含むメソッドの呼び出しに対応しているが、プラットフォーム固有のフレームや
VM 内部のフレームには対応していません。
フレームに関する情報は次の構造体で戻されます。
typedef struct {
jmethodID method;
jlocation location;
} jvmtiFrameInfo;
フレームセットに関する情報は次の構造体で戻されます。
typedef struct {
jthread thread;
jint state;
jvmtiFrameInfo* frame_buffer;
jint frame_count;
} jvmtiStackInfo;
スタックトレースの取得
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
関数を使用できます。このマッピングは、遅延してもかまいません。
プラットフォーム依存のメソッド呼び出しを使ってスレッドを起動する場合、これらの呼び出しをスタックとレースに含めることができます。この場合、main()
や run() よりも深いフレームが存在することになります。
この関数は、 ライブ段階でしか呼び出せません。
パラメータ |
名前 |
型 |
説明 |
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 を呼び出す
- スレッドを再開する
ポップされたフレームに対するロックは、ポップ時に解放されます。これは、ポップされた同期化メソッドや、その中の同期化ブロックにも当てはまります。し
かし、ネイティブロックには当てはまりません。
最終的に、ブロックは実行されません。
グローバル状態への変更には対応しないので、変更は行われません。
現在のスレッドを指定することはできません。中断したスレッドを指定してください。
呼び出されるメソッドと呼び出し側のメソッドのどちらも、非ネイティブの Java プログラミング言語のメソッドとします。
この関数は、JVMTI イベントを生成しません。
この関数は、 ライブ段階でしか呼び出せません。
|
フレームの位置の取得
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 |
フレームのポップイベントが生成されるフレームの深さ |
|
ヒープ
ヒープ関数:
ヒープ関数の型:
これらの関数は、ヒープの分析に使用されます。ヒープ内のオブジェクトの表示、これらのオブジェクトへのタグ付けなどの機能があります。
「タグ」は、オブジェクトに関連付けられる値です。タグは、エージェントにより、タグの設定
関
数を使って明示的に設定されます。または、jvmtiHeapObjectCallback
などのコールバック関数によって設定されます。
タグは環境に対してローカルです。つまり、ある環境のタグを別の環境で表示することはできません。
タグは jlong
値です。この値を使って、オブジェクトにマークを付けたり、詳細情報のポインタを格納したりできます。タグ付けされていないオブジェクトには、ゼロのタグ
が付いています。タグをゼロに設定することにより、オブジェクトのタグ付けを解除できます。
原理の説明: ヒープダンプ機能 (下記)
は、各オブジェクトにコールバックを使用します。バッファ方式のほうがスループットが高いように思われますが、テストでは、そのような結果は得られませ
ん。メモリ参照の場所または配列アクセスのオーバヘッドによるものと考えられます。
タグの取得
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 ForceGarbageCollection(jvmtiEnv* env)
VM
にガベージコレクションの実行を強制します。ガベージコレクションは可能なかぎり完全に行われます。この関数は、ファイナライザを実行させません。この関
数は、ガベージコレクションが完了するまで終了しません。
この関数は、 ライブ段階でしか呼び出せません。
|
ヒープオブジェクトのコールバック
typedef jvmtiIterationControl (JNICALL *jvmtiHeapObjectCallback) (jlong class_tag, jlong size, jlong* tag_ptr, void* user_data);
エージェントによって提供されるコールバック関数。ヒープ内のオブジェクトを説明しますが、値は渡しません。
繰り返し処理を継続する場合、戻り値は JVMTI_ITERATION_CONTINUE
です。繰り返し処理を停止する場合、戻り値は JVMTI_ITERATION_ABORT です。
このコールバックでは、JNI 関数は使用できません。このコールバックでは、特別に使用が許可されている JVMTI 関数以外を使用できません
(raw モニター関数、メモリ管理関数、環境ローカル記憶領域関数を参照)。
パラメータ |
名前 |
型 |
説明 |
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 です。
このコールバックでは、JNI 関数は使用できません。このコールバックでは、特別に使用が許可されている JVMTI 関数以外を使用できません
(raw モニター関数、メモリ管理関数、環境ローカル記憶領域関数を参照)。
|
スタック参照オブジェクトのコールバック
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 です。
このコールバックでは、JNI 関数は使用できません。このコールバックでは、特別に使用が許可されている JVMTI 関数以外を使用できません
(raw モニター関数、メモリ管理関数、環境ローカル記憶領域関数を参照)。
|
オブジェクト参照のコールバック
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 です。
このコールバックでは、JNI 関数は使用できません。このコールバックでは、特別に使用が許可されている JVMTI 関数以外を使用できません
(raw モニター関数、メモリ管理関数、環境ローカル記憶領域関数を参照)。
|
オブジェクトから到達可能なオブジェクトの繰り返し
jvmtiError IterateOverObjectsReachableFromObject(jvmtiEnv* env, jobject object, jvmtiObjectReferenceCallback object_reference_callback, void* user_data)
この関数は、指定されたオブジェクトから直接または間接的に到達可能なすべてのオブジェクトに対して繰り返し処理を行います。オブジェクト B
を参照する各オブジェクト A (参照側オブジェクト)
に対して、指定されたコールバック関数が呼び出され、オブジェクト参照について説明します。コールバックは、参照側からの参照のたびに 1
回だけ呼び出されます。参照サイクルや、参照側のパスが複数存在する場合も同様です。参照側と参照される側の間に、複数の参照が存在する場合があります。
これらの識別には、jvmtiObjectReference.reference_
(種類) と jvmtiObjectReference.referrer_
(インデックス) を使用します。オブジェクトのコールバックは、常に参照側のコールバックのあとで行われます。
この関数の実行中、ヒープのステータスは変化しません。オブジェクトの割り当てやガベージコレクションは行われません。よって、オブジェクト
(格納されている値も含む) は変更されません。結果として、Java プログラミング言語のコードを実行するスレッド、Java
プログラミング言語のコードの実行を再開しようとしているスレッド、JNI 関数を実行しようとしているスレッドは、停止します。
この関数は、 ライブ段階でしか呼び出せません。
|
到達可能なオブジェクトの繰り返し
jvmtiError IterateOverReachableObjects(jvmtiEnv* env, jvmtiHeapRootCallback heap_root_callback, jvmtiStackReferenceCallback stack_ref_callback, jvmtiObjectReferenceCallback object_ref_callback, void* user_data)
この関数は、ルートオブジェクトと、ルートオブジェクトから直接または間接的に到達可能なすべてのオブジェクトに対して繰り返し処理を行います。ルートオ
ブジェクトは、システムクラス、JNI
グローバル、スレッドスタックからの参照、ガベージコレクションの目的でルートとして使用されるその他のオブジェクトのセットで構成されます。
各ルートに、heap_root_callback ま
たはstack_root_callback が
呼び出されます。オブジェクトは、1
つ以上の理由でルートオブジェクトになることができます。この場合、個々の理由に対して適切なコールバックが呼び出されます。
各オブジェクト参照に、object_ref_callback 関
数が呼び出され、オブジェクト参照について説明します。コールバックは、参照側からの参照のたびに 1
回だけ呼び出されます。参照サイクルや、参照側のパスが複数存在する場合も同様です。参照側と参照される側の間に、複数の参照が存在する場合があります。
これらの識別には、jvmtiObjectReference.reference_
(種類) と jvmtiObjectReference.referrer_
(インデックス) を使用します。オブジェクトのコールバックは、常に参照側のコールバックのあとで行われます。
ルートは、常に、オブジェクト参照が報告される前に、プロファイラに報告されます。つまり、object_ref_callback は、
すべてのルートに対して適切なコールバックが呼び出されるまで、呼び出されません。object_ref_callback が
NULL と指定されている場合、この関数は、プロファイラにルートオブジェクトを報告したあと、終了します。
この関数の実行中、ヒープのステータスは変化しません。オブジェクトの割り当てやガベージコレクションは行われません。よって、オブジェクト
(格納されている値も含む) は変更されません。結果として、Java プログラミング言語のコードを実行するスレッド、Java
プログラミング言語のコードの実行を再開しようとしているスレッド、JNI 関数を実行しようとしているスレッドは、停止します。
この関数は、 ライブ段階でしか呼び出せません。
|
ヒープの繰り返し
jvmtiError IterateOverHeap(jvmtiEnv* env, jvmtiHeapObjectFilter object_filter, jvmtiHeapObjectCallback heap_object_callback, 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, void* user_data)
指定されたクライアントのインスタンスになっている、ヒープ内のすべてのオブジェクトに対して繰り返し処理を行います。到達可能なオブジェクトも、そうで
ないオブジェクトも含まれます。
object_filter
パラメータは、どのオブジェクトのためにコールバック関数が呼び出されるかを示します。パラメータが JVMTI_HEAP_OBJECT_TAGGED
の場合、コールバックは、すべてのタグ付きオブジェクトに対してのみ呼び出されます。パラメータが JVMTI_HEAP_OBJECT_UNTAGGED
の場合、コールバックは、すべてのタグなしオブジェクトに対してのみ呼び出されます。パラメータが JVMTI_HEAP_OBJECT_EITHER
の場合、コールバックは、タグが付いているかどうかに関係なく、ヒープ内のすべてのオブジェクトに対して呼び出されます。
この関数の実行中、ヒープのステータスは変化しません。オブジェクトの割り当てやガベージコレクションは行われません。よって、オブジェクト
(格納されている値も含む) は変更されません。結果として、Java プログラミング言語のコードを実行するスレッド、Java
プログラミング言語のコードの実行を再開しようとしているスレッド、JNI 関数を実行しようとしているスレッドは、停止します。
この関数は、 ライブ段階でしか呼び出せません。
|
タグを使ったオブジェクトの取得
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
の場合、この情報は返されない
|
|
局所変数
局所変数関数:
これらの関数は、局所変数の値を取得または設定するために使います。変数は、変数の値を含んでいるフレームの深さと、そのフレーム内の変数のスロット番号
によって識別されます。変数からスロット番号へのマッピングは、関数 GetLocalVariableTable
を使って取得できます。
局所変数の取得 - オブジェクト
jvmtiError GetLocalObject(jvmtiEnv* env, jthread thread, jint depth, jint slot, jobject* value_ptr)
この関数は、 ライブ段階でしか呼び出せません。
パラメータ |
名前 |
型 |
説明 |
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)
GetLocalInt は、int 、char 、byte 、
および boolean 型の値の取得に使うことができます。
この関数は、 ライブ段階でしか呼び出せません。
|
局所変数の取得 - 長整数型
jvmtiError GetLocalLong(jvmtiEnv* env, jthread thread, jint depth, jint slot, jlong* value_ptr)
この関数は、 ライブ段階でしか呼び出せません。
|
局所変数の取得 - 浮動小数点数型
jvmtiError GetLocalFloat(jvmtiEnv* env, jthread thread, jint depth, jint slot, jfloat* value_ptr)
この関数は、 ライブ段階でしか呼び出せません。
|
局所変数の取得 - 倍精度浮動小数点数型
jvmtiError GetLocalDouble(jvmtiEnv* env, jthread thread, jint depth, jint slot, jdouble* value_ptr)
この関数は、 ライブ段階でしか呼び出せません。
|
局所変数の設定 - オブジェクト型
jvmtiError SetLocalObject(jvmtiEnv* env, jthread thread, jint depth, jint slot, jobject value)
この関数は、 ライブ段階でしか呼び出せません。
|
局所変数の設定 - 整数型
jvmtiError SetLocalInt(jvmtiEnv* env, jthread thread, jint depth, jint slot, jint value)
SetLocalInt は、int 、char 、byte 、
および boolean 型の値の設定に使うことができます。
この関数は、 ライブ段階でしか呼び出せません。
|
局所変数の設定 - 長整数型
jvmtiError SetLocalLong(jvmtiEnv* env, jthread thread, jint depth, jint slot, jlong value)
この関数は、 ライブ段階でしか呼び出せません。
|
局所変数の設定 - 浮動小数点数型
jvmtiError SetLocalFloat(jvmtiEnv* env, jthread thread, jint depth, jint slot, jfloat value)
この関数は、 ライブ段階でしか呼び出せません。
|
局所変数の設定 - 倍精度浮動小数点数型
jvmtiError SetLocalDouble(jvmtiEnv* env, jthread thread, jint depth, jint slot, jdouble value)
この関数は、 ライブ段階でしか呼び出せません。
|
ブレークポイント
ブレークポイント関数:
ブレークポイントの設定
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
コードからのフィールドアクセスが監視され、ほかの手段で変更されるフィールドは監視されません。JVMTI
のユーザは、自分自身のフィールドアクセスによって監視イベントがトリガされることに注意してください。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
コードからのフィールド変更が監視され、ほかの手段で変更されるフィールドは監視されません。JVMTI
のユーザは、自分自身で実行するフィールド変更によって監視イベントがトリガされることに注意してください。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 個以上のビットがセットされます。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
ソースファイル名の取得
jvmtiError GetSourceFileName(jvmtiEnv* env, jclass klass, char** source_name_ptr)
klass で指定されたクラスについて、source_name_ptr
を介してソースファイル名を返します。返される UTF-8 文字列は、ファイル名だけで、ディレクトリ名は含まれません。
プリミティブクラス (たとえば、java.lang.Integer.TYPE ) および配列の場合、この関数は JVMTI_ERROR_ABSENT_INFORMATION
を返します。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
クラスの修飾子の取得
jvmtiError GetClassModifiers(jvmtiEnv* env, jclass klass, jint* modifiers_ptr)
klass で指定されたクラスのアクセスフラグを、modifiers_ptr
を介して返します。アクセスフラグは Java
仮想マシン仕様で定義されています。
クラスが配列クラスの場合、その public、private および protected
修飾子は、そのコンポーネント型の修飾子と同じです。プリミティブ型の配列の場合、このコンポーネント型は、プリミティブクラスの 1 つ (たとえば、java.lang.Integer.TYPE )
で表現されます。
クラスがプリミティブクラスの場合、その public 修飾子は常に true になります。また、その protected 修飾子および
private 修飾子は常に false になります。
クラスが配列クラスまたはプリミティブクラスの場合、その final 修飾子は常に true になり、interface 修飾子は常に
false になります。その他の修飾子の値は、この仕様では判定されません。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
クラスのメソッドの取得
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 )
の場合、空のメソッドリストが返されます。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
クラスのフィールドの取得
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 IsInterface(jvmtiEnv* env, jclass klass, jboolean* is_interface_ptr)
クラスオブジェクト参照がインタフェースを表しているかどうかを判定します。クラスが実際にインタフェースである場合、jboolean
は JNI_TRUE を返し、インタフェースではない場合には JNI_FALSE
を返します。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
配列クラスかどうかの検査
jvmtiError IsArrayClass(jvmtiEnv* env, jclass klass, jboolean* is_array_class_ptr)
クラスオブジェクト参照が配列を表しているかどうかを判定します。jboolean は、クラスが配列である場合は JNI_TRUE
になり、そのでない場合は JNI_FALSE になります。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
クラスローダの取得
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
を介して返します。返される UTF-8 文字列には、klass
ファイルに存在するデバッグ拡張情報がそのまま含まれます。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
クラスの再定義
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)
指定されたクラスはすべて、提供される定義に従って再定義されます。使用方法については、バイトコードインストゥルメン
テーションの説明を参照してください。
再定義されたメソッドにアクティブなスタックフレームがあると、そのアクティブフレームは元のメソッドのバイトコードの実行を続行します。これらのメソッ
ドは廃棄されました。再定義したメソッドは、新しい呼び出しで使用されます。廃棄されたメソッドかどうかをテストするには、IsMethodObsolete
を使用します。元のメソッド ID は再定義されたメソッドを参照します。スタックフレームをリセットする場合は、破棄されたメソッドとともに PopFrame を使用し、フレームをポップしてください。
元のメソッドと再定義したメソッドが同等とみなされるのは、次のような場合です。
- 双方のメソッドのバイトコードが同じ (定数プールのインデックスを除く)
- 参照定数が等しい
この関数により、一般的な JVM
セマンティクスのもとで行われる以外の初期化は起こりません。つまり、クラスを再定義しても、そのクラスの初期化は実行されません。static
フィールドの値は、呼び出し前の状態のままです。
スレッドを中断する必要はありません。
クラス内のブレークポイントは解除されます。
属性はすべて更新されます。
再定義されたクラスのインスタンスは影響を受けません。フィールドは以前の値を保持します。インスタンス上のタグも、
影響を受けません。
この呼び出しに答えて、JVMTI イベントとしてクラスファイルロードフックが送
信されます (有効な場合)。しかし、その他の JVMTI イベントは送信されません。
再定義によって、メソッドの本体、定数プール、属性が変更されることがあります。再定義によって、フィールドやメソッドの追加、削除、名前の変更、メソッ
ドのシグニチャーの変更、修飾子の変更、継承の変更が起きないようにする必要があります。これらの制限は、将来のバージョンで解除される可能性がありま
す。サポートされていない再定義が試行されたとき返されるエラーコードについては、下記のエラー戻り値の説明を参照してください。
この関数は、 ライブ段階でしか呼び出せません。
|
Object
オブジェクト関数:
オブジェクトの型:
オブジェクトサイズの取得
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
を介して返します。オブジェクト参照のハッシュテーブルを管理するために、このハッシュコードを使用できます。しかし、一部の実装では、パフォーマンスが
大幅に低減する可能性があります。ほとんどの場合、情報とオブジェクトの関連付けには、タグを使うほうが効果的
です。この関数は、特定のオブジェクトの持続期間中ずっと、そのオブジェクトのハッシュコード値が同じであることを保証します。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
オブジェクトのモニターの利用情報を取得
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
構造体のフィールドに、モニターの使用に関する情報が入ります。
この関数は、 ライブ段階でしか呼び出せません。
パラメータ |
名前 |
型 |
説明 |
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 、スーパークラス、または実装されたインタフェースのどれかです。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
フィールドの修飾子の取得
jvmtiError GetFieldModifiers(jvmtiEnv* env, jclass klass, jfieldID field, jint* modifiers_ptr)
klass と field で指定されたフィールドのアクセスフラグを、modifiers_ptr
を介して返します。アクセスフラグは Java
仮想マシン仕様で定義されています。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
合成フィールドかどうかの検査
jvmtiError IsFieldSynthetic(jvmtiEnv* env, jclass klass, jfieldID field, jboolean* is_synthetic_ptr)
klass および field で指定されたフィールドに対し、is_synthetic_ptr
を介してそのフィールドが合成であるかどうかを示す値を返します。合成フィールドはコンパイラによって生成されますが、元のソースコード内には存在しませ
ん。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
メソッド
メソッド関数:
メソッドの型:
メソッドの名前とシグニチャーの取得
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
を介して返します。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
メソッドの修飾子の取得
jvmtiError GetMethodModifiers(jvmtiEnv* env, jmethodID method, jint* modifiers_ptr)
method で指定されたメソッドのアクセスフラグを、modifiers_ptr
を介して返します。アクセスフラグは Java
仮想マシン仕様で定義されています。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
局所変数の取得
jvmtiError GetMaxLocals(jvmtiEnv* env, jmethodID method, jint* max_ptr)
method で指定されたメソッドによって使用される局所変数
(呼び出し時にメソッドにパラメータを渡すために使用される局所変数を含む) のスロット数を返します。
『JavaTM 仮想マシン仕様』の「Code
Attribute」のセクションの max_locals の説明を参照してください。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
引数のサイズの取得
jvmtiError GetArgumentsSize(jvmtiEnv* env, jmethodID method, jint* size_ptr)
method で指定されたメソッドの引数によって使用される局所変数のスロット数を、max_ptr
を介して返します。なお、2 ワードの引数は、スロットを 2 つ使用します。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
行番号テーブルの取得
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 を介して返されます。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
メソッドの配置位置の取得
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 を引いた値をポイントします。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
局所変数テーブルの取得
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)
局所変数の情報を返します。
この関数は、 ライブ段階でしか呼び出せません。
パラメータ |
名前 |
型 |
説明 |
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
を介して返します。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
合成メソッドかどうかの検査
jvmtiError IsMethodSynthetic(jvmtiEnv* env, jmethodID method, jboolean* is_synthetic_ptr)
method で指定されたメソッドが合成メソッドかどうかを表す値を、is_synthetic_ptr
を介して返します。合成メソッドは、コンパイラによって生成されますが、元のソースコード内には存在しません。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
廃棄されたメソッドかどうかの検査
jvmtiError IsMethodObsolete(jvmtiEnv* env, jmethodID method, jboolean* is_obsolete_ptr)
このメソッドが RedefineClasses
で廃棄されたメソッドかどうかを検査します。
この関数は、 開始またはライブ段階でしか呼び出せません。
|
raw モニター
raw モニター関数:
raw モニターの作成
jvmtiError CreateRawMonitor(jvmtiEnv* env, const char* name, jrawMonitorID* monitor_ptr)
raw モニターを作成します。
この関数は、 OnLoad またはライブ段階でしか呼び出せません。
この関数は、ヒープ繰り返し関数のコールバックから呼び出せます。GarbageCollectionStart
イベント、GarbageCollectionFinish
イベント、ObjectFree
イベントのイベントハンドラからの呼び出しも可能です。
パラメータ |
名前 |
型 |
説明 |
name |
const char* |
モニターを識別する UTF-8 形式の名前
エージェントは char に配列を渡す。 |
monitor_ptr |
jrawMonitorID* |
戻ったとき、作成されたモニターをポイントする
エージェントは jrawMonitorID にポインタを渡す。戻ったとき、jrawMonitorID
が設定されている |
|
raw モニターの破棄
jvmtiError DestroyRawMonitor(jvmtiEnv* env, jrawMonitorID monitor)
raw
モニターを破棄します。破棄されるモニターがこのスレッドによって入力された場合、破棄される前に終了します。破棄されるモニターが別のスレッドによって
入力された場合、エラーが返され、モニターの破棄は行われません。
この関数は、 OnLoad またはライブ段階でしか呼び出せません。
この関数は、ヒープ繰り返し関数のコールバックから呼び出せます。GarbageCollectionStart
イベント、GarbageCollectionFinish
イベント、ObjectFree
イベントのイベントハンドラからの呼び出しも可能です。
|
raw モニターの開始
jvmtiError RawMonitorEnter(jvmtiEnv* env, jrawMonitorID monitor)
raw モニターの排他的所有権を取得します。同じスレッドで複数回モニターを入力することができます。スレッドは、モニターを入力回数分だけ終了する必要があります。モニターが OnLoad
(接続されたスレッドが生成される前)
の段階で入力され、接続されたスレッドが生成された時点で終了していない場合、入力はメインスレッドで行われたと認識されます。
この関数は、 どの段階でも呼び出し可能です。
この関数は、ヒープ繰り返し関数のコールバックから呼び出せます。GarbageCollectionStart
イベント、GarbageCollectionFinish
イベント、ObjectFree
イベントのイベントハンドラからの呼び出しも可能です。
|
raw モニターの終了
raw モニターの待機
raw モニターの通知
raw モニターの通知 (すべて)
JNI 関数の遮断
JNI 関数の遮断関数:
Java Native Interface (JNI) 関数テーブルの操作により、JNI
関数呼び出しの遮断および再送信の機能を提供します。『Java Native Interface 仕様』の「JNI
Functions」の説明を参照してください。
次に、カウント参照の作成順に 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 関数テーブルの取得
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
が呼び出された順番は、結果に影響を及ぼしません。
この関数は、 OnLoad またはライブ段階でしか呼び出せません。
|
イベント通知モードの設定
typedef enum { JVMTI_ENABLE = 1, JVMTI_DISABLE = 0 } jvmtiEventMode;
jvmtiError SetEventNotificationMode(jvmtiEnv* env, jvmtiEventMode mode, jvmtiEvent event_type, jthread event_thread, ...)
イベントの生成を制御します。
thread が NULL
の場合は、このイベントはグローバルに有効または無効にされます。そうでない場合は、特定のスレッドについて有効または無効にされます。特定のスレッドに
ついてイベントが生成されるのは、イベントがスレッドレベルまたはグローバルレベルのどちらかで有効にされている場合です。
個々のイベントについての情報は、後述する説明を参照してください。
次のイベントは、この関数を使ってスレッドレベルでは制御できません。
最初は、スレッドレベルで有効にされているイベントも、グローバルレベルで有効にされているイベントもありません。
この関数を呼び出す前に、必要な権限 (後述の「イベントを有効化する権限」を参照) を所有している必要があります。
イベントの詳細については、後述します。
この関数は、 OnLoad またはライブ段階でしか呼び出せません。
|
イベントの生成
jvmtiError GenerateEvents(jvmtiEnv* env, jvmtiEvent event_type)
現在の VM のステータスを表すイベントを生成します。たとえば、event_type
が JVMTI_EVENT_COMPILED_METHOD_LOAD の場合、最近コンパイルされた各メソッドに CompiledMethodLoad
イベントが送信されます。ロードされてから、まだアンロードされていないメソッドは送信されません。以前に送信されたイベントの履歴は、送信されるイベン
トに影響を及ぼしません。このメソッドが呼び出されるたびに、最近コンパイルされたすべてのメソッドが送信されます。
エージェントがプログラムの実行開始後に接続されたことにより、イベントが失われた場合は、この関数を使って失われたイベントを生成できます。
Java プログラミング言語コードまたは JNI
関数の実行は、この関数が終了するまで一時停止することができます。そのため、どちらもイベントを送信するスレッドから呼び出されないようにする必要があ
ります。この関数は、失われたイベントが送信され、処理されて終了するまで終了しません。イベントが、発生元のスレッドとは別のスレッドに送信されること
があります。イベントを発生させるためには、SetEventCallbacks
でイベントのコールバックを設定し、SetEventNotificationMode
でイベントを有効にする必要があります。要求されたイベントの一部またはすべてを生成するために必要な情報が VM
から失われた場合、イベントは送信されず、エラーも返されません。
サポートされるイベントは次のとおりです。
この関数は、 ライブ段階でしか呼び出せません。
|
拡張機能機構
拡張機能機構関数:
拡張機能機構関数の型:
拡張機能機構の型:
JVMTI 実装は、これらの関数を使って、この仕様に定義されていない関数およびイベントを提供します。
拡張関数と拡張イベントのパラメータは、それぞれ次の表に示す「型」と「種類」を持ちます。
typedef struct {
char* name;
jvmtiParamKind kind;
jvmtiParamTypes base_type;
jboolean null_ok;
} jvmtiParamInfo;
拡張関数
typedef jvmtiError (JNICALL *jvmtiExtensionFunction) (jvmtiEnv* jvmti_env, ...);
実装固有の拡張関数です。
|
拡張関数の取得
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)
拡張関数のセットを返します。
この関数は、 OnLoad またはライブ段階でしか呼び出せません。
パラメータ |
名前 |
型 |
説明 |
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)
拡張イベントのセットを返します。
この関数は、 OnLoad またはライブ段階でしか呼び出せません。
パラメータ |
名前 |
型 |
説明 |
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, ...)
「... 」は変数引数を表します。
|
拡張イベントコールバックの設定
jvmtiError SetExtensionEventCallback(jvmtiEnv* env, jint extension_event_index, jvmtiExtensionEvent callback)
拡張イベントにコールバック関数を設定し、イベントを有効にします。コールバックが NULL
の場合、イベントを無効にします。標準イベントとは異なり、コールバックを設定してイベントを有効にする処理は単一の操作です。
この関数は、 OnLoad またはライブ段階でしか呼び出せません。
|
権限
権限関数:
権限の型:
権限関数では、JVMTI が使用できる機能 (どの JVMTI
関数を呼び出せるか、どんなイベントを生成できるか、これらのイベントや関数がどんな機能を提供できるかなど) を変更できます。
各関数およびイベントの「権限」のセクションには、関連付けられている権限の説明が記載されています
(存在する場合)。「必要な機能」は、使用可能であり、権限を追加しなくても使用できることを表しています。「任意の機能」は、使用するためにはエージェ
ントに権限が必要であることを表しています。権限を持つためには、エージェントは権限を追加す
る必要があります。「任意の機能」には、機能セットを拡張する権限の説明が記載されています。
各 JVMTI 実装が潜在的に使用できる権限は異なります。実装によって、次のようなことが言えます。
- 決して追加してはならない権限がある
- すべての環境で、ある権限を
OnLoad
またはライブ段階で追加できる
- ある権限を
OnLoad
段階でしか追加できない
- ある権限を複数の環境で同時に所有することはできない
- ある権限を複数の環境で同時に所有することはできない。また、
OnLoad
段階でしか所有できない
- その他
しばしば、権限を追加することによって、実行速度、起動時間、メモリフットプリントなどに影響が出ることがあります。権限を使用するオーバーヘッドは、権
限を所有するオーバーヘッドとはまったく異なる点に注意してください。例として、ステップ実行について考えてみましょう。ステップ実行が有効な場合は
(イベントが有効で、アクティブにイベントを送信している状態)、どの実装でも、各命令でイベントを送信し、処理するオーバーヘッドが大きくなります。一
方、権限を所有するオーバーヘッドは、実装によって大きかったり小さかったりします。また、権限を潜在的に使用できるかどうかも、実装によって異なりま
す。使用例を次に示します。
- ある VM
は、バイトコードをネイティブコードにコンパイルすることによってすべてを実行し、ステップ実行命令を生成できなくなっている。この実装では、権限は追加
できない
- 別の VM
は、実行をステップ実行インタプリタにいつでも切り替えられる。この実装では、権限を所有することでオーバーヘッドは生じず、権限はいつでも追加できる
- さらに別の VM
は、バイトコードのコンパイルまたはステップ実行可能な解釈済み実行エンジンを起動時に選択できるが、これらを切り替えることはできない。この実装では、
OnLoad
段階 (バイトコードの実行を開始する前) で権限を追加する必要がある。ステップ実行を使用したことがない場合でも、実行速度にはかなりの影響がある
- さらに別の VM は、コンパイル済みバイトコードまたは生成済みインタプリタに [is single stepping on]
チェックを追加できる。この実装でも、
OnLoad
段階で権限を追加する必要があるが、オーバーヘッド
(各命令のテストとブランチ) はかなり低くなる
JVMTI 環境ごとに、固有の権限セットがあります。最初、このセットは空です。必要な権
限があれば、追加します。可能であれば、権限は 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) { ... } }
権限の構造体
これらの関数は、各権限に対応したブール型のフラグを含む、権限の構造体 (jvmtiCapabilities
)
を使用します。
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 : 15;
unsigned int : 16;
unsigned int : 16;
unsigned int : 16;
unsigned int : 16;
unsigned int : 16;
} jvmtiCapabilities;
jvmtiCapabilities
- JVMTI 接続の権限 |
すべての型は unsigned int : 1 |
フィールド |
説明 |
|
can_tag_objects |
ヒープのカテゴリに説明されているように、タグを設定し、取得できる |
|
can_generate_field_modification_events |
フィー
ルドの変更に監視ポイントを設定できる - SetFieldModificationWatch
|
|
can_generate_field_access_events |
フィー
ルドアクセスに監視ポイントを設定できる - SetFieldAccessWatch
|
|
can_get_bytecodes |
メソッド GetBytecodes のバイトコードを取得できる |
|
can_get_synthetic_attribute |
合成
フィールドまたは合成メソッドであるかどうかをテストできる - IsFieldSynthetic
と IsMethodSynthetic |
|
can_get_owned_monitor_info |
モニ
ターの所有に関する情報を取得できる - GetOwnedMonitorInfo
|
|
can_get_current_contended_monitor |
GetCurrentContendedMonitor
を実行できる |
|
can_get_monitor_info |
GetObjectMonitorUsage
を実行できる |
|
can_pop_frame |
スタックからフレームをポップでき
る - PopFrame |
|
can_redefine_classes |
RedefineClasses
でクラスを再定義できる。元のメソッドと再定義されたメソッドのバイトコードが一致している必要はない。定数プールと属性も、一致している必要はない |
|
can_signal_thread |
スレッドに停止または割り
込み信号を送信できる |
|
can_get_source_file_name |
クラスの
ソースファイルの名前を取得できる |
|
can_get_line_numbers |
メソッドの行番号
テーブルを取得できる |
|
can_get_source_debug_extension |
ク
ラスのソースデバッグ拡張機能を取得できる |
|
can_access_local_variables |
局所変
数を設定し、取得できる |
|
can_maintain_original_method_order |
ク
ラスファイル内に出現する順序でメソッドを返すことができる |
|
can_generate_single_step_events |
ステップ実行イベントを取得できる |
|
can_generate_exception_events |
スローされた例外と例外キャッチイ
ベントを取得できる |
|
can_generate_frame_pop_events |
FramePop イベントを設定し、取得することができる |
|
can_generate_breakpoint_events |
Breakpoint イベントを設定し、取得することができる |
|
can_suspend |
スレッドを中断し、再開できる |
|
can_redefine_any_class |
RedefineClasses
は任意のクラスで呼び出せる (can_redefine_classes
も設定する必要がある) |
|
can_get_current_thread_cpu_time |
現在のスレッド CPU 時間を取得できる |
|
can_get_thread_cpu_time |
スレッド
CPU 時間を取得できる |
|
can_generate
_method_entry_events |
メソッドの入力時にメソッド入力イベントを生成できる |
|
can_generate
_method_exit_events |
メソッドの終了時にメソッド終了イベントを生成できる |
|
can_generate
_all_class_hook_events |
ロードされたすべてのクラスに対して、ClassFileLoadHook イベントを生成できる |
|
can_generate
_compiled_method_load_events |
メ
ソッドのコンパイル時またはアンロード時にイベントを生成できる |
|
can_generate
_monitor_events |
モニターの使用率に関するイベントを生成できる |
|
can_generate
_vm_object_alloc_events |
オブジェクトの VM 割り当てに関するイベントを生成できる |
|
can_generate
_native_method_bind_events |
ネイティブメソッドが実装にバインドされているときイベントを生成できる |
|
can_generate
_garbage_collection_events |
ガベージコレクションの開始または終了時にイベントを生成できる |
|
can_generate
_object_free_events |
ガベージコレクタがオブジェクトを解放するときにイベントを生成できる |
|
潜在的な権限の取得
jvmtiError GetPotentialCapabilities(jvmtiEnv* env, jvmtiCapabilities* capabilities_ptr)
capabilities_ptr
を介して、現時点でこの環境が所有できる JVMTI 機能を返します。返される機能が、VM
が実装する完全な権限セットとは異なる場合があります。該当するのは、別の環境が、複数の環境による所有を許可されていない権限を所有している場合、そし
て現在の段階がライブ段階で、特定の権限は OnLoad
段階でしか追加できない場合です。これらの権限の一部またはすべてを設定するには、AddCapabilities
関数を使用できます。現在所有されている権限が含まれます。
通常、この関数は、OnLoad
関数で使用されます。一部の仮想マシンでは、ライブ段階で追加できる権限のセットが制限されています。この場合、潜在的に使用可能な権限のセットが、OnLoad
段階のセットとは異なります。
「権限の例」を参照してください。
この関数は、 OnLoad またはライブ段階でしか呼び出せません。
|
権限の追加
jvmtiError AddCapabilities(jvmtiEnv* env, const jvmtiCapabilities* capabilities_ptr)
capabilities_ptr
によってポイントされている権限を追加することにより、新しい権限を設定します。以前の権限はすべて保持されます。通常、この関数は、OnLoad
関数で使用されます。一部の仮想マシンでは、ライブ段階で追加できる権限のセットが制限されています。
「権限の例」を参照してください。
この関数は、 OnLoad またはライブ段階でしか呼び出せません。
|
権限の放棄
jvmtiError RelinquishCapabilities(jvmtiEnv* env, const jvmtiCapabilities* capabilities_ptr)
capabilities_ptr
によってポイントされる権限を放棄します。実装によっては、単一の環境にしか権限の所有が許可されない場合があります (「権限の概要」を参照)。この関数は、その他のエージェントが使用できるように、権限を解放します。そ
の他のすべての権限は保持されます。権限は、GetCapabilities
からは失われます。エージェントが所有していない権限を放棄しようとしても、エラーは発生しません。
この関数は、 OnLoad またはライブ段階でしか呼び出せません。
|
機能の取得
jvmtiError GetCapabilities(jvmtiEnv* env, jvmtiCapabilities* capabilities_ptr)
capabilities_ptr
を介して、この環境が現在所有している任意の JVMTI 機能を返します。環境は、AddCapabilities
を使って追加に成功するまで、権限を所有しません。環境は、RelinquishCapabilities
を使って放棄しないかぎり、権限を失いません。したがって、この関数は、AddCapabilities 呼び出しと RelinquishCapabilities
呼び出しの最終結果を返します。
「権限の例」を参照してください。
この関数は、 どの段階でも呼び出し可能です。
|
タイマー
タイマー関数:
タイマーの型:
これらの関数は、タイミング情報を提供します。時間が更新される精度は指定されていません。ナノ秒単位の精度が提供されますが、必ずしもナノ秒単位の精密
度が得られるとは限りません。最大値など、タイマーの詳細情報には、タイマー情報関数を使ってアクセスできます。各タイマーの情報関数は、次のデータ構造
体を返します。
typedef struct {
jlong max_value;
jboolean may_skip_forward;
jboolean may_skip_backward;
jvmtiTimerKind kind;
jlong reserved1;
jlong reserved2;
} jvmtiTimerInfo;
タイマーの種類は次のとおりです。
現在のスレッドの CPU タイマー情報を取得
現在のスレッドの CPU 時間を取得
jvmtiError GetCurrentThreadCpuTime(jvmtiEnv* env, jlong* nanos_ptr)
現在のスレッドによって使用されている CPU 時間を返します。
GetThreadCpuTime
関数は、現在のスレッドを含むあらゆるスレッドの CPU 時間を提供します。GetCurrentThreadCpuTime
は、現在のスレッドまたは現在のスレッドよりも精密な情報を持つスレッド以外のスレッドの CPU
時間を提供できないプラットフォームをサポートします (GetCurrentThreadCpuTimerInfo
と GetThreadCpuTimerInfo
を参照)。多くのプラットフォームでは、この呼び出しは次のコードと同等です。
GetThreadCpuTime(env, NULL, nanos_ptr)
この関数は、 開始またはライブ段階でしか呼び出せません。
この関数は、ヒープ繰り返し関数のコールバックから呼び出せます。GarbageCollectionStart
イベント、GarbageCollectionFinish
イベント、ObjectFree
イベントのイベントハンドラからの呼び出しも可能です。
パラメータ |
名前 |
型 |
説明 |
nanos_ptr |
jlong* |
戻ったとき、このスレッドによって使用される CPU 時間 (ナノ秒単位)
をポイントするこれは符号なしの値。jlong (符号付きの値) としてテストまたは出力した場合、負の数値として表示される場合がある
エージェントは jlong にポインタを渡す。戻ったとき、jlong が設定されている |
|
スレッドの CPU タイマー情報を取得
スレッドの 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 GetTime(jvmtiEnv* env, jlong* nanos_ptr)
システムタイマーの現在の値 (ナノ秒単位) を返します。
返される値は、固定された任意の時間からの経過時間 (ナノ秒)
です。将来的に、値が負の数になる可能性があります。この関数では、ナノ秒単位の精度が提供されますが、必ずしもナノ秒単位の精密度が得られるとは限りま
せん。値の変更頻度は保証されません。
GetTimerInfo
により、このタイマーの情報を取得します。
この関数は、 どの段階でも呼び出し可能です。
この関数は、ヒープ繰り返し関数のコールバックから呼び出せます。GarbageCollectionStart
イベント、GarbageCollectionFinish
イベント、ObjectFree
イベントのイベントハンドラからの呼び出しも可能です。
パラメータ |
名前 |
型 |
説明 |
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)
ブー
トストラップクラスローダがクラスの検索に失敗したあと、指定されたプラットフォーム依存の検索パスセグメント を
検索します。この関数では、ブートストラップクラスローダを使ってインストゥルメンテーションクラスを定義できます。セグメント 内
に指定できるセグメント (通常はディレクトリまたは JAR ファイル) は 1
個だけです。複数のセグメントを追加したい場合、この関数を複数回呼び出すことができます。セグメントは、この関数が呼び出された順に検索されます。
この関数は、 OnLoad またはライブ段階でしか呼び出せません。
パラメータ |
名前 |
型 |
説明 |
segment |
const char* |
プラットフォーム依存の検索パスセグメント
エージェントは 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 メソッド呼び出しを使用できます。
プロパティのセットは、実行中に増えることがあります。
この関数は、 OnLoad またはライブ段階でしか呼び出せません。
パラメータ |
名前 |
型 |
説明 |
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 メソッド呼び出しを使用できます。
この関数は、 OnLoad またはライブ段階でしか呼び出せません。
パラメータ |
名前 |
型 |
説明 |
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
を参照してください。
この関数は、 OnLoad またはライブ段階でしか呼び出せません。
パラメータ |
名前 |
型 |
説明 |
property |
const char* |
プロパティの UTF-8 キー
エージェントは char に配列を渡す。 |
値 |
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 実行の現在の段階を返します。段階は次の順で進行します。
起動に失敗した場合、VM は中間の段階を省略して直接デッド段階に進みます。この場合、VMInit イベントも VMDeath
イベントも送信されません。
ほとんどの JVMTI 関数は、ライブ段階でしか動作しません。次の関数は、OnLoad
段階でもライブ段階でも動作します。
次の関数は、OnLoad 段階でもライブ段階でも動作します。
次の関数は、開始段階でもライブ段階でも動作します。
次の関数は、どの段階でも動作します。
JNI 関数 (呼び出し API を除く) は、開始段階またはライブ段階で使用する必要があります。
ほとんどの JVMTI イベントは、ライブ段階でしか送信されません。次のイベントは、その他の段階で扱われます。
この関数は、 どの段階でも呼び出し可能です。
パラメータ |
名前 |
型 |
説明 |
phase_ptr |
jvmtiPhase* |
戻ったとき、段階をポイントする
エージェントは jvmtiPhase にポインタを渡す。戻ったとき、jvmtiPhase
が設定されている |
|
環境の破棄
jvmtiError DisposeEnvironment(jvmtiEnv* env)
JNI GetEnv で作成された JVMTI 接続を停止します (JVMTI
Environments を参照)。環境が保持していたすべてのリソースを破棄します。
中断したスレッドは再開されていません。この処理は、エージェントによって明示的に行われる必要があります。割り当てられたメモリは解放されていません。
この処理は、エージェントによって明示的に行われる必要があります。この環境は、この呼び出しのあとは使用できません。この呼び出しは呼び出し元に戻りま
す。
この関数は、 どの段階でも呼び出し可能です。
|
環境ローカル記憶領域の設定
jvmtiError SetEnvironmentLocalStorage(jvmtiEnv* env, const void* data)
VM
は、個々の環境に関連付けられたポインタ値を格納します。このポインタ値を「環境ローカルな記憶領域」と呼びます。この関数で設定されない場合、値は NULL
になります。エージェントは、環境固有の情報を格納するため、メモリを割り当てることができます。環境ローカルな記憶領域を設定することにより、GetEnvironmentLocalStorage
を使ってアクセスできるようになります。
JVMTI の環境ローカルな記憶領域の値を設定するため、エージェントによって呼び出されます。JVMTI
は、エージェントに対して、環境ごとの情報を記録するために利用できる、ポインタサイズの環境ローカルな記憶領域を提供します。
この関数は、 どの段階でも呼び出し可能です。
この関数は、ヒープ繰り返し関数のコールバックから呼び出せます。GarbageCollectionStart
イベント、GarbageCollectionFinish
イベント、ObjectFree
イベントのイベントハンドラからの呼び出しも可能です。
パラメータ |
名前 |
型 |
説明 |
data |
const void * |
環境ローカルな記憶領域に入力する値
エージェントは配列を渡す。data が NULL の場合、値は NULL
に設定される
|
|
環境ローカル記憶領域の取得
バージョン番号の取得
jvmtiError GetVersionNumber(jvmtiEnv* env, jint* version_ptr)
JVMTI のバージョンが version_ptr
によって返されます。戻り値はバージョン識別子です。バージョン識別子には、インタフェースの型と、メジャーバージョン番号、マイナーバージョン番号、マ
イクロバージョン番号が含まれます。
この関数は、 どの段階でも呼び出し可能です。
パラメータ |
名前 |
型 |
説明 |
version_ptr |
jint* |
戻ったとき、JVMTI のバージョンをポイントする
エージェントは jint にポインタを渡す。戻ったとき、jint が設定されている |
|
エラー名の取得
jvmtiError GetErrorName(jvmtiEnv* env, jvmtiError error, char** name_ptr)
エラーコードのシンボリック名を返します。
たとえば、GetErrorName(env, JVMTI_ERROR_NONE, &err_name) は、err_name
に文字列 "JVMTI_ERROR_NONE" を返します。
この関数は、 どの段階でも呼び出し可能です。
|
冗長フラグの設定
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)
冗長出力を制御します。これは、通常 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
から返される配列のインデックスとして使用できます。
この関数は、 どの段階でも呼び出し可能です。
パラメータ |
名前 |
型 |
説明 |
format_ptr |
jvmtiJlocationFormat* |
戻ったとき、jlocation 値の形式識別子をポイントする
エージェントは jvmtiJlocationFormat にポインタを渡す。戻ったとき、jvmtiJlocationFormat
が設定されている |
|
エラー
JVMTI 関数はすべて、jvmtiError
エラーコードを返します。
エージェントは、有効なパラメータを持つ JVMTI 関数を、適切なコンテキスト (たとえば、呼び出し側スレッドが接続されていて、段階が適切)
で呼び出します。実装によって、一部のエラー条件の検出が困難であったり、非効率的であったり、不可能であったりします。実装は、「関数固有の必須エラー」に一覧されているエラーを検出する必要があります。その他のエラーは、エラー条
件に対する推奨されている応答を表します。
汎用エラー
次のエラーは、どの関数からも返される可能性があるエラーです。
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)
- 指定された JVMTI 環境はもう接続されていない、または環境ではない
JVMTI_ERROR_WRONG_PHASE
(112)
- 現在の段階では、必要な機能を使用できない。仮想マシンが実行を完了している場合、常に返
される
JVMTI_ERROR_INTERNAL (113)
- 予期しない内部エラーが発生した
関数固有の必須エラー
一部の JVMTI 関数は、次のエラーを返します。これらのエラーは、条件が満たされたとき、実装によって返される必要があります。
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
関数から返される可能性があるエラーです。これらのエラーは、エージェントによって無効なパラメータが渡された場合や、無効なコンテキストで使用された場
合に返されます。これらのエラーは、実装なしで検出できます。
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)
- 新しいクラスのバージョンのメソッドの修飾子が旧クラスのバージョンの修飾子と異なる
データ型
JVMTI は、JNI によって定義されたデータ型を拡張します。
JVMTI で使用する 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 プログラミング言語フィールドを識別する |
jmethodID |
Java
プログラミング言語メソッド、イニシャライザ、またはコンストラクタを識別する |
JNIEnv |
JNI 関数テーブルのポインタ。JNIEnv *
のポインタは JNI 環境 |
JVMTI 基底型 |
型 |
説明 |
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;
|
イベント
イベントの処理
エージェントは、アプリケーションプログラム内で発生する多くのイベントについての通知を受けることができます。
イベントを処理するには、SetEventCallbacks
を使ってコールバック関数のセットを指定します。イベントごとに、対応するコールバック関数が呼び出されます。コールバック関数の引数は、イベントに関す
る追加情報を提供します。コールバック関数は、通常、アプリケーションスレッド内から呼び出されます。JVMTI
実装は、どんな形でもイベントをキューに入れません。これは、イベントのコールバック関数を注意深く記述する必要があることを意味しています。このあと、
一般的なガイドラインを説明します。さらに詳しい提案については、個々のイベントの説明を参照してください。
- イベントコールバック関数の実行中にスローされた例外は、現在のアプリケーションスレッド内で現在保留中の例外を上書きできてしまう。した
がって、例外を生成する可能性のある JNI
呼び出しをイベントコールバック関数から実行する場合は、保留中の例外を保存するように気を付けなければならない
- イベントコールバック関数は、再入可能でなければならない。JVMTI
実装は、イベントをキューに入れない。エージェントが複数のイベントを一度に 1 つずつ処理する必要がある場合は、イベントコールバック関数の内部で
raw モニターを使うと、イベントの処理を直列化できる
- JNI の FindClass 関数を実行してクラスをロードするイベントコールバック関数については、FindClass
が現在のネイティブメソッドに関連付けされたクラスローダを見つけることに注意する必要があります。クラスのロードのために、コールバックのパラメータと
して JNI 環境を含むイベントコールバックは、イベントスレッドで実行される現在のクラスのネイティブメソッドとして閲覧できます。
JVMTI イベントの中には、JNI 参照を使ってオブジェクトを識別するものがあります。JVMDI イベント内のすべての参照は、JNI
ローカル参照で、イベントコールバック関数から復帰すると無効になります。記述されていない場合、イベントから送信されたポインタによって参照されるメモ
リは、イベントの終了後は参照できません。
イベントは、関数 SetEventNotificationMode
を使って有効および無効にできます。すべてのイベントは、初期段階では無効になっています。したがって、イベントを受信するには、次のようにします。
記述されていない場合、イベントは、そのイベントを引き起こしたスレッドに配信されます。イベントは、発生と同時に送信されます。各イベントの仕様には、
このイベントを送信できる段階についての記述が含まれています。イベントを送信できる段階以外の段階で
イベントをトリガしても、イベントは送信されません。
イベントの実行ステータスが、イベントの生成元スレッドによって変更されることはありません。たとえば、スレッドがイベントによって中断されることはあり
ません。イベントを中断させる必要のあるエージェントは、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;
jvmtiEventDataResetRequest DataResetRequest;
jvmtiEventMonitorWait MonitorWait;
jvmtiEventMonitorWaited MonitorWaited;
jvmtiEventMonitorContendedEnter MonitorContendedEnter;
jvmtiEventMonitorContendedEntered MonitorContendedEntered;
jvmtiEventReserved reserved77;
jvmtiEventReserved reserved78;
jvmtiEventReserved reserved79;
jvmtiEventReserved reserved80;
jvmtiEventGarbageCollectionStart GarbageCollectionStart;
jvmtiEventGarbageCollectionFinish GarbageCollectionFinish;
jvmtiEventObjectFree ObjectFree;
jvmtiEventVMObjectAlloc VMObjectAlloc;
} jvmtiEventCallbacks;
イベントの索引
ステップ実行
void JNICALL
SingleStep(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jmethodID method,
jlocation location)
ステップ実行イベントを利用すると、JVMDI クライアントは、VM
で可能な最小の単位でスレッドの実行を追跡できます。ステップ実行イベントは、スレッドが新しい位置に達するたびに生成されます。通常、ステップ実行イベ
ントは、『Java 仮想マシン仕様』に定義されているように、1 つの VM
命令が完了したことを示します。ただし、位置の定義が異なる実装もあります。いずれにしても、method
および location
パラメータによって現在の位置を一意に識別できるため、この情報があればソースファイルと行番号へのマッピングが可能です。
ネイティブメソッド内からは、ステップ実行イベントは生成されません。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_SINGLE_STEP = 60
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_SINGLE_STEP, NULL)
ブレークポイント
void JNICALL
Breakpoint(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jmethodID method,
jlocation location)
ブレークポイントイベントは、SetBreakpoint
を使ってブレークポイントとして指定された位置にスレッドが達した時点で生成されます。method
および location
パラメータによって現在の位置を一意に識別できるため、この情報があればソースファイルと行番号へのマッピングが可能です。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_BREAKPOINT = 62
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_BREAKPOINT, NULL)
フィールドアクセス
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
パラメータによって現在の位置を一意に識別できるため、この情報があればソースファイルと行番号へのマッピングが可能です。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_FIELD_ACCESS = 63
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_FIELD_ACCESS, NULL)
フィールドの変更
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
パラメータによって現在の位置を一意に識別できるため、この情報があればソースファイルと行番号へのマッピングが可能です。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_FIELD_MODIFICATION = 64
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_FIELD_MODIFICATION, NULL)
フレームのポップ
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
によりレポートされる位置は、復帰しようとしているメソッド内の復帰直前の実行可能位置を識別します。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_FRAME_POP = 61
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_FRAME_POP, NULL)
メソッドエントリ
void JNICALL
MethodEntry(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jmethodID method)
メソッドエントリイベントは、Java プログラミング言語メソッド (ネイティブメソッドを含む) に入る時点で生成されます。
GetFrameLocation
によりレポートされる位置は、メソッド内の初期実行可能位置を識別します。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_METHOD_ENTRY = 65
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_METHOD_ENTRY, NULL)
メソッド終了
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
によりレポートされる位置は、復帰しようとしているメソッド内の復帰直前の実行可能位置を識別します。
多くのプラットフォームでは、メソッドエントリイベントまたはメソッド終了イベントを有効にすると、パフォーマンスが大幅に低下します。したがって、プロ
ファイリングなど、パフォーマンスを重視する処理での使用はお勧めしません。これらの場合には、バイトコードインストゥル
メンテーションを使用すべきです。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_METHOD_EXIT = 66
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_METHOD_EXIT, NULL)
ネイティブメソッドのバインド
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 およびほとんどの JVMTI
はこの時点で使用することができませんが、メソッドおよびアドレスは保存して後で使用できます。
このイベントは、 初期段階、開始段階、およびライブ段階で送信されます。
イベント ID:
JVMTI_EVENT_NATIVE_METHOD_BIND = 67
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_NATIVE_METHOD_BIND, NULL)
Exception
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
プログラミング言語メソッドによってスローされる場合と、ネイティブメソッドによってスローされる場合があります。ネイティブメソッドによってスローされ
る場合は、その例外が Java
プログラミング言語メソッドによって最初に認識されるまで、このイベントは生成されません。例外がネイティブメソッド内で生成されて解除された場合
(つまり、Java プログラミング言語コードからは認識されない場合) は、例外イベントは生成されません。
method
および location
パラメータによって現在の位置
(例外が検出された位置) を一意に識別できるため、この情報があればソースファイルと行番号へのマッピングが可能です。exception
フィールドは、スローされた例外オブジェクトを認識します。catch_method
および catch_location
は、スローされた例外を処理する catch 節の位置を識別します (そのような節が存在する場合)。そのような catch
節がない場合、それらの各フィールドは 0 に設定されます。スレッドがこの catch
節に到達するという保証はありません。呼び出しスタック上で例外スローの位置と catch
節の間にネイティブメソッドがある場合、それらのネイティブメソッドのどれかによって例外がリセットされる可能性があるからです。同様に、キャッチされな
いとレポートされた例外 (catch_klass
et al. に 0 を設定)
は、実際にはネイティブコードによってキャッチされます。エージェントは、これらの発生を、ExceptionCatch
イベントを監視することによってチェックします。finally
節は、キャッチ/再スローとして実装される点に注意してください。このため、これらはキャッチの位置でレポートされます。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_EXCEPTION = 58
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_EXCEPTION, NULL)
例外キャッチ
void JNICALL
ExceptionCatch(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jmethodID method,
jlocation location,
jobject exception)
例外キャッチイベントは、スローされた例外がキャッチされた時点で生成されます。例外が Java
プログラミング言語メソッド内でキャッチされた場合は、catch
節に到達した時点でこのイベントが生成されます。例外がネイティブメソッド内でキャッチされた場合は、Java
プログラミング言語メソッドに制御が戻った直後にこのイベントが生成されます。例外キャッチイベントは、Java
プログラミング言語メソッド内でスローが検出された例外に対して生成されます。finally
節は、キャッチ/再スローとして実装される点に注意してください。このため、これらは例外キャッチイベントを生成します。
method
および location
パラメータによって現在の位置を一意に識別できるため、この情報があればソースファイルと行番号へのマッピングが可能です。Java
プログラミング言語メソッド内でキャッチされた例外の場合は、exception
オブジェクトが例外オブジェクトを識別します。ネイティブメソッド内でキャッチされた例外は、例外のキャッチがレポートされた時点で入手可能とは限らない
ので、exception
フィールドは NULL
に設定されます。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_EXCEPTION_CATCH = 59
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_EXCEPTION_CATCH, NULL)
スレッドの開始
void JNICALL
ThreadStart(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread)
スレッド開始イベントは、新しいスレッドによって、スレッドの初期メソッドが実行される前に、生成されます。
スレッド開始イベントが生成される前に、GetAllThreads
によって返される配列に、そのスレッドが含まれている可能性があります。また、スレッド開始イベントの前に、その他のイベントがスレッド上に生成される可
能性があります。
イベントは新しく開始された thread
に送信されます。
このイベントは、 開始段階またはライブ段階で送信されます。
イベント ID:
JVMTI_EVENT_THREAD_START = 52
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_THREAD_START, NULL)
スレッドの終了
void JNICALL
ThreadEnd(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread)
スレッド終了イベントは、停止しようとしているスレッドによって、スレッドの初期メソッドの実行完了後に、生成されます。
スレッド終了イベントが生成されたあと、GetAllThreads
によって返される配列に、そのスレッドが含まれている可能性があります。スレッド終了イベントのあと、スレッド上にイベントは生成されません。
イベントは終了する thread
に送信されます。
このイベントは、 開始段階またはライブ段階で送信されます。
イベント ID:
JVMTI_EVENT_THREAD_END = 53
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_THREAD_END, NULL)
クラスのロード
void JNICALL
ClassLoad(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jclass klass)
クラスロードイベントは、クラスが最初にロードされた時点で生成されます。特定のスレッドによりクラスロードイベントが生成される順序は、そのスレッド内
でクラスがロードされる順序と一致することが保証されています。配列クラスの作成では、クラスロードイベントは生成されません。プリミティブクラス
(java.lang.Integer.TYPE など) の作成では、クラスロードイベントは生成されません。
このイベントは、クラスのロードの早い段階で送信されます。このため、クラスは慎重に使用する必要があります。たとえば、メソッドやフィールドがまだロー
ドされておらず、メソッド、フィールド、サブクラスが照会されていない場合、正しい結果は得られません。『Java 言語仕様』の「Loading
of Classes and Interfaces」を参照してください。ほとんどの場合、ClassPrepare
の方が有効です。
このイベントは、 開始段階またはライブ段階で送信されます。
イベント ID:
JVMTI_EVENT_CLASS_LOAD = 55
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_CLASS_LOAD, NULL)
クラスの準備
void JNICALL
ClassPrepare(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jclass klass)
クラス準備イベントは、クラスの準備が完了した時点で生成されます。この時点では、クラスのフィールド、メソッド、および実装されたインタフェースが利用
可能ですが、クラスのコードはまだ何も実行されていません。配列クラスは、フィールドやメソッドを持つことがないため、配列クラスについてクラス準備イベ
ントが生成されることはありません。プリミティブクラス (たとえば、java.lang.Integer.TYPE
)
についても、クラス準備イベントは生成されません。
このイベントは、 開始段階またはライブ段階で送信されます。
イベント ID:
JVMTI_EVENT_CLASS_PREPARE = 56
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_CLASS_PREPARE, NULL)
クラスファイルロードフック
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 がクラスファイルデータを取得したとき、そのクラスのメモリ内部表現を構築する前の時点で送信されます。任意の JVMTI 環境で RedefineClasses
が呼び出されたときも送信されます。エージェントは、VM
によって送信された既存のクラスファイルデータに、プロファイリング/デバッグフックを計測することができます。使用方法については、バイトコードインストゥルメンテーションの説明を参照してください。
このイベントは、VM の初期化前に送信される可能性があります。この時点では、VM リソースは作成されません。関数 (たとえば ROMized
classes) との互換性がないクラスについては、このイベントは生成されません。
エージェントは、メモリ割り当て関数 Allocate
を使って、修正したクラスファイルデータのバッファ用の領域を割り当てる必要があります。新しいクラスファイルデータのバッファを解放する処理は、VM
により、Deallocate
を使って実行されるからです。
エージェントは、クラスファイルを変更したい場合、新しく実装されたクラスファイルデータバッファをポイントするように new_class_data
を設定し、この呼び出しから戻る前に、new_class_data_len
にそのバッファの長さを設定する必要があります。変更が不要な場合、エージェントは new_class_data
を設定しません。複数のエージェントがこのイベントを有効にしている場合、結果はチェーンになります。つまり、new_class_data
が設定されている場合は、これが次のエージェントの class_data
になります。すべてのイベントについて、環境が作成された順番でエージェントが呼び出されます。
このイベントは、 初期段階、開始段階、およびライブ段階で送信されます。
イベント ID:
JVMTI_EVENT_CLASS_FILE_LOAD_HOOK = 54
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL)
VM 開始イベント
void JNICALL
VMStart(jvmtiEnv *jvmti_env,
JNIEnv* jni_env)
VM 初期化イベントは、VM の開始を示します。この時点で JNI はライブですが、VM
はまだ完全に初期化されていません。このイベントが生成されたあとは、エージェントは任意の JNI
関数を自由に呼び出すことができます。このイベントは、開始段階の開始を示します。開始段階で許可された JVMTI 関数を呼び出すことができます。
VM の起動に失敗した場合、このイベントは送信されません。
このイベントは、 開始段階またはライブ段階で送信されます。
イベント ID:
JVMTI_EVENT_VM_START = 57
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_VM_START, NULL)
VM 初期化イベント
void JNICALL
VMInit(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread)
VM 初期化イベントは、VM の初期化の完了を示します。このイベントが生成されたあとは、エージェントは任意の JNI または JVMTI
関数を自由に呼び出すことができます。VM
初期化イベントは、その前に他のイベントが生成されたり、他のイベントと同時に生成されたりすることがあります。そのうち、VM
初期化イベントの前の生成されるイベントについては、VM
の初期化がまだ完了していないので、特に注意して処理する必要があります。メインアプリケーションスレッドのスレッド開始イベントは、VM
初期化イベントのハンドラが復帰するまでは発生しないことが保証されています。
VM の起動に失敗した場合、このイベントは送信されません。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_VM_INIT = 50
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_VM_INIT, NULL)
VM 終了イベント
void JNICALL
VMDeath(jvmtiEnv *jvmti_env,
JNIEnv* jni_env)
VM 終了イベントは、VM の終了をエージェントに通知します。VMDeath イベントのあとは、イベントは発生しません。
VM の起動に失敗した場合、このイベントは送信されません。こうした場合、Agent_OnUnload
は呼び出される点に注意してください。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_VM_INIT = 51
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_VM_DEATH, NULL)
コンパイル済みメソッドのロード
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
によって送信することができます。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_COMPILED_METHOD_LOAD = 68
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_COMPILED_METHOD_LOAD, NULL)
コンパイル済みメソッドのアンロード
void JNICALL
CompiledMethodUnload(jvmtiEnv *jvmti_env,
jmethodID method,
const void* code_addr)
コンパイルされたメソッドがメモリからアンロードされる時点で送信されます。このイベントは、アンロードを実行したスレッド上に送信されないことがありま
す。このイベントは、アンロードの発生後に送信される場合があります。しかし、新しく生成されたコンパイル済みメソッドによってメモリが再使用される前に
送信されます。このイベントは、クラスのアンロード後に送信される可能性があります。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_COMPILED_METHOD_UNLOAD = 69
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_COMPILED_METHOD_UNLOAD, NULL)
パラメータ |
名前 |
型 |
説明 |
method |
jmethodID |
アンロードされる、コンパイルされたメソッドコンパイルされたメソッドを識別する目的しか持たない。クラスはアンロードされるため、メソッドを以後の
JNI または JVMTI 関数の引数として使用できない |
code_addr |
const void* |
コンパイルされたメソッドコードがロードされたアドレス。コンパイルされたメソッドを識別する目的しか持たない。空間は再生されている可能性がある |
動的コード生成
void JNICALL
DynamicCodeGenerated(jvmtiEnv *jvmti_env,
const char* name,
const void* address,
jint length)
仮想マシンのコンポーネントが動的に生成されるときに送信されます。これは、コンパイルされる Java プログラミング言語コードには対応しません (CompiledMethodLoad
を参照)。これはネイティブコード向けではありません。たとえば、生成されるインタプリタは、コマンド行オプションによって異なります。
このイベントには、制御機能はありません。VM は、これらのイベントを生成できない場合、何も送信しません。
これらのイベントは、最初の発生のあと、GenerateEvents
によって送信することができます。
このイベントは、 初期段階、開始段階、およびライブ段階で送信されます。
イベント ID:
JVMTI_EVENT_DYNAMIC_CODE_GENERATED = 70
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_DYNAMIC_CODE_GENERATED, NULL)
パラメータ |
名前 |
型 |
説明 |
name |
const char* |
コードの名前。エンドユーザへの表示用。名前は一意でなくてもよい |
address |
const void* |
コードのネイティブアドレス |
length |
jint |
コードの長さ (バイト単位) |
データダンプ要求
void JNICALL
DataDumpRequest(jvmtiEnv *jvmti_env)
VM
によって送信され、エージェントにデータをダンプするよう要求します。これは単に示唆しているだけであり、エージェントはこのイベントに必ずしも反応する
必要はありません。これは、ユーザからのコマンド行シグナルを処理する場合に便利です。たとえば、JDK の場合、Win32 上では
Ctrl+Break キー、Solaris 上では Ctrl+\ キーで、このイベントは VM からエージェントへ送信されます。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_DATA_DUMP_REQUEST = 71
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_DATA_DUMP_REQUEST, NULL)
データリセット要求
void JNICALL
DataResetRequest(jvmtiEnv *jvmti_env)
VM
によって送信され、エージェントにデータをリセットするよう要求します。これは単に示唆しているだけであり、エージェントはこのイベントに必ずしも反応す
る必要はありません。これは、ユーザからのコマンド行シグナルを処理する場合に便利です。たとえば、JDK の場合、Win32 上では
Ctrl+Break キー、Solaris 上では Ctrl+\ キーで、このイベントは VM からエージェントへ送信されます。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_DATA_RESET_REQUEST = 72
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_DATA_RESET_REQUEST, NULL)
競合するモニターの選択
void JNICALL
MonitorContendedEnter(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jobject object)
スレッドが Java プログラミング言語モニターに入ろうとしたとき、そのモニターがすでに別のスレッドによって獲得されている場合に送信されます。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_MONITOR_CONTENDED_ENTER = 75
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_MONITOR_CONTENDED_ENTER, NULL)
競合するモニターの開始
void JNICALL
MonitorContendedEntered(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jobject object)
別のスレッドが Java プログラミング言語モニターを解放するのを待ったあとで、スレッドがその Java モニターに入るときに送信されます。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_MONITOR_CONTENDED_ENTERED = 76
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, NULL)
モニター待機
void JNICALL
MonitorWait(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jobject object,
jlong timeout)
スレッドがオブジェクトを待機しようとしているときに送信されます。このスレッドは、Object.wait()
に入るスレッドです。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_MONITOR_WAIT = 73
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_MONITOR_WAIT, NULL)
モニター待機終了
void JNICALL
MonitorWaited(jvmtiEnv *jvmti_env,
JNIEnv* jni_env,
jthread thread,
jobject object,
jboolean timed_out)
スレッドがオブジェクトの待機を終了するときに送信されます。このスレッドは、Object.wait()
を出るスレッドです。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_MONITOR_WAITED = 74
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_MONITOR_WAITED, NULL)
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 内部オブジェクト
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_VM_OBJECT_ALLOC = 84
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_VM_OBJECT_ALLOC, NULL)
オブジェクトの解放
void JNICALL
ObjectFree(jvmtiEnv *jvmti_env,
jlong tag)
オブジェクトの解放イベントは、ガベージコレクタがオブジェクトを解放した時点で送信されます。イベントは、タグ付きオブジェクトの場合にのみ送信されま
す (heap functions を参照)。
イベントハンドラは、特別に使用が許可されている JVMTI 関数以外の関数および JNI 関数を使用できません (raw
モニター関数、メモリ管理関数、環境ローカル記憶領域関数を参照)。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_OBJECT_FREE = 83
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_OBJECT_FREE, NULL)
ガベージコレクションの開始
void JNICALL
GarbageCollectionStart(jvmtiEnv *jvmti_env)
ガベージコレクションの開始イベントは、ガベージコレクションの全サイクルが開始されたとき送信されます。処理を停止する
(stop-the-world) コレクション、つまりすべてのスレッドが Java
仮想マシンのステータスの変更を終了している間に収集されるコレクションだけがレポートされます。このため、コレクタによっては、これらのイベントを生成
しません。このイベントは、VM がまだ停止している間に送信されるので、イベントハンドラは、特別に使用が許可されている JVMTI
関数以外の関数および JNI 関数を使用できません (raw モニター関数、メモリ管理関数、環境ローカル記憶領域関数を参照)。
このイベントは、常に GarbageCollectionFinish
と一致するペア (どちらのイベントも有効と見なされる) として送信され、これらの間に、ガベージコレクションイベントは発生しません。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_GARBAGE_COLLECTION_START = 81
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_GARBAGE_COLLECTION_START, NULL)
ガベージコレクションの完了
void JNICALL
GarbageCollectionFinish(jvmtiEnv *jvmti_env)
ガベージコレクションの終了イベントは、ガベージコレクションの全サイクルが終了したとき送信されます。このイベントは、VM
がまだ停止している間に送信されるので、イベントハンドラは、特別に使用が許可されている JVMTI 関数以外の関数および JNI
関数を使用できません (raw モニター関数、メモリ管理関数、環境ローカル記憶領域関数を参照)。
一部のエージェントは、許可されていない JVMTI または JNI
関数を使用する必要のある、ガベージコレクション後の操作を行う必要があります。そのような場合、raw
モニターで待機するエージェントスレッドを作成でき、ガベージコレクションの終了イベントでは、単に raw モニターに通知します。
このイベントは、常に GarbageCollectionStart
と一致するペア (どちらのイベントも有効と見なされる) として送信されます。
このイベントは、 ライブ段階でしか送信されません。
イベント ID:
JVMTI_EVENT_GARBAGE_COLLECTION_FINISH = 82
有効化:
すべてのイベントは、初期段階では無効になっています。次のようにしてグローバルに有効化します。
SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, NULL)
定数の索引
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_OBJECT_EITHER
JVMTI_HEAP_OBJECT_TAGGED
JVMTI_HEAP_OBJECT_UNTAGGED
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_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_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
変更履歴
最終更新日:04/04/30 15:28:54
ファイルのバージョン:@(#)jvmti.xml 1.127
バージョン: 0.3.27
バージョン
日付 |
変更点 |
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 日 |
以前の概要情報を削除、JVMTI Environments
セクションを追加 |
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 を削除 (オペランドスタックは JVMTI では使用されない)。説明を修正:起動時間の定義、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 では保持されるが JVMTI
からは削除。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 日 |
JVMTI から 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.10.87
2003 年 8 月 5 日 |
GetErrorName を追加。jvmtiExtensionEvent
に変数引数の警告を追加。jvmtiExtensionEvent の jvmtiEnv* から定数を削除。使用されない
can_get_exception_info 機能を削除。jvmtiStartFunction に jvmtiEnv* と JNIEnv*
を渡す。jvmtiExtensionFunctionInfo.func
の宣言型を修正。拡張関数はエラーコードを返す。バージョン番号付け方式を新規化 |
0.20.88
2003 年 8 月 5 日 |
ClassUnload イベントを削除 |
0.20.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.20.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 または JVMTI
を含まない。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
の使用法の例にパラメータを追加 |