現在、Java Virtual Machine。の仕様をさらに掘り下げようとしています。私は オンラインのJVM本の中 を読んでいます。把握しているようです:コンスタントプールここに本からの抜粋があります:
ロードするタイプごとに、Java仮想マシンは定数プールを格納する必要があります。定数プールは、リテラル(文字列、整数、浮動小数点定数を含む)型、フィールド、およびメソッドへのシンボリック参照定数プール内のエントリは、配列の要素と同様に、インデックスによって参照されます。型によって使用されるすべての型、フィールド、およびメソッドへのシンボリック参照を保持するため、定数プールはJavaプログラムの動的リンクで中心的な役割を果たします
上記およびCPに関する一般的な質問がいくつかあります。
.class
ファイルにありますか?ダイアグラムを使用してフレームがどのように構築されるかを理解することが役立つと思います。
フレームは、オペランド(操作命令)が存在する場所であり、動的リンクが発生する場所です。これは、クラスとそのメンバーを追跡するために定数プールを使用する、いわば短縮形の方法です。
各フレームには、ランタイム定数プールへの参照が含まれています。参照は、そのフレームに対して実行されているメソッドのクラスの定数プールを指します。この参照は、動的リンクのサポートに役立ちます。
通常、C/C++コードはオブジェクトファイルにコンパイルされ、複数のオブジェクトファイルがリンクされて、実行可能ファイルやdllなどの使用可能なアーティファクトが生成されます。リンクフェーズ中に、各オブジェクトファイルのシンボリック参照は、最終的な実行可能ファイルに対する実際のメモリアドレスに置き換えられます。 Javaこのリンクフェーズは、実行時に動的に行われます。
Javaファイルがコンパイルされると、変数およびメソッドへのすべての参照は、シンボリック参照としてクラスの定数プールに格納されます。シンボリック参照は、実際に物理を指す参照ではなく論理参照ですメモリの場所。
詳細は James Blooms JVM Internals へのリンクです。
定数プールは、そのクラスのコードを実行するために必要な定数を含む_.class
_ファイル(およびそのメモリ内表現)の一部です。
これらの定数には、プログラマーによって指定されたリテラルとコンパイラーによって生成されたシンボリック参照が含まれます。シンボリック参照は、基本的にコードから参照されるクラス、メソッド、およびフィールドの名前です。これらの参照は、JVMがコードを依存する他のクラスにリンクするために使用されます。
たとえば、次のコード
_System.out.println("Hello, world!");
_
次のバイトコードを生成します(javap
出力)
_0: getstatic #2; //Field Java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3; //String Hello, world!
5: invokevirtual #4; //Method Java/io/PrintStream.println:(Ljava/lang/String;)V
_
_#n
_は、定数プールへの参照です。 _#2
_は_System.out
_フィールドへのシンボリック参照、_#3
_は_Hello, world!
_文字列、_#4
_はPrintStream.println(String)
メソッドへのシンボリック参照です。
ご覧のとおり、シンボリック参照は単なる名前ではありません。たとえば、メソッドへのシンボリック参照には、パラメータ(_Ljava/lang/String;
_)および戻り値の型(V
はvoid
を意味します)も含まれます。
クラスの_javap -verbose
_を実行することにより、クラスの定数プールを検査できます。
簡単な英語でのコンスタントプールの目的は何ですか?
CPは、冗長性を減らすために非常に一意の定数値が保存されるメモリ領域です。
System.err.println("Hello");
System.out.println("Hello");
CPにはStringオブジェクト「Hello」が1つしかなく、コンパイラーは両方の行で同じ参照に置き換えます。 .classファイルには、1つのHello文字列のみが含まれます。 (他のタイプでも同じです)。
CPは各タイプの.Classファイルにありますか?
はい、こちらをご覧ください: http://en.wikipedia.org/wiki/Java_class_file
最初に例を挙げて、文字列定数プールの意味を理解しましょう
public class StringConstantPool {
public static void main(String[] args) {
String s = "prasad";
String s2 = "prasad";
System.out.println(s.equals(s2));
System.out.println(s == s2);
}
}
出力は
true
true
ここで何が起こるか
1-クラスは、JVMが呼び出されたときにロードされます。
2- JVMは、プログラム内のすべての文字列リテラルを探します。
3-最初に、リテラルを参照するvariable sを見つけます“ prasad”メモリに作成されます
4-リテラル“ prasad”の参照は、文字列定数プールメモリに配置されます。
5-次に、同じ文字列リテラルを参照している別のvariable s2を見つけます“ prasad“ =。
JVMがすでに文字列リテラル“ prasad“を検出したため、変数sとs2の両方が同じオブジェクトを参照しますすなわち“ prasad“。
これがお役に立てば幸いです
続きを読む http://www.journaldev.com/797/what-is-Java-string-pool