私は最近、この興味深い用語に出くわし、それについて詳しく知るためにネットで検索しました。しかし、私が見つけた情報は大ざっぱです。誰か教えてください。これが何であり、なぜこれが役立つのかについて、ある程度詳しく説明してください。
私が見つけた情報から、このメカニズムはリフレクション メソッドの実行を高速化するように見えますが、多くの動的クラスを作成し、perm gen メモリ領域を占有しますが、それについてはよくわかりません。
私は最近、この興味深い用語に出くわし、それについて詳しく知るためにネットで検索しました。しかし、私が見つけた情報は大ざっぱです。誰か教えてください。これが何であり、なぜこれが役立つのかについて、ある程度詳しく説明してください。
私が見つけた情報から、このメカニズムはリフレクション メソッドの実行を高速化するように見えますが、多くの動的クラスを作成し、perm gen メモリ領域を占有しますが、それについてはよくわかりません。
これを理解するために、ソースコードを掘り下げて自分でコーディングしたところ、次のことがわかりました。
Java の「メソッド」クラスには、メソッドの呼び出しと同様に、メソッド「呼び出し」とのインターフェースである「メソッドアクセス」型のメンバー変数「メソッドアクセス」があります。メソッドの呼び出しは、methodAccessor の呼び出しに委譲します。
インフレーションが有効な場合 (noInflation が false)、このアクセサーは、JNI を使用してこの Java メソッドを実行する実装を指します (GetObjectClass、GetMethodID、Call*Method などの API を使用すると思います)。これはデュエル ディスパッチのようなもので、JNI での実行はこれやその他の理由で遅くなります。( JNI 呼び出しが遅くなる原因は何ですか? )
リフレクションによるメソッドの 15 回の実行後 ('15' はデフォルトであり、変更可能)、noInflation が false の場合、JNI ベースのアクセサーはその場でクラスを作成します (名前は動的に生成されます。たとえば、'GeneratedMethodAccessor1' など)。呼び出しメソッド。ここで、この「invoke」メソッド内で、最初の「obj」引数を対応するクラスにキャストし、それに対してターゲット メソッドを呼び出します。次に、このクラスのインスタンスを作成し、メソッドのすべての実行が JNI アクセサーではなくこのインスタンスに委譲されるように、methodAccessor 設定を変更します。これをインフレといいます。
このインスタンスは Java オブジェクトに委譲する Java クラスであるため、以降の委譲は通常の Java 委譲です。JNI には決して行かないため、そのオーバーヘッドが節約されます。さらに、JITC はそれに対して他の最適化を実行できるため、効率的になります。
欠点は、多くのメソッドがこのように拡張されると、それらのクラスが permgen スペースを占有し、メモリ不足エラーが発生する可能性があることです。
詳細については、次を参照してください。
http://java.sun.com/docs/books/jni/html/fldmeth.html
http://anshuiitk.blogspot.com/2010/11/excessive-full-garbage-collection.html
確かではありませんが、どこかでこれを読んでくださいインフレとは、反映されたメソッド/コンストラクターの最初の数回の実行 (デフォルトは 15) で (今後、メソッドへの参照はコンストラクターにも適用されます)、JNI を介して実行されることを意味します。次回以降は、その場でクラス ファイルをアセンブルし、ロードします。その時点で、完全な JITting が適用され、その反映されたメソッドへのさらなる呼び出しは、そのメソッドを直接呼び出した場合と同じパフォーマンスになります。