78

私は現在、Java 仮想マシンの仕様をより深く掘り下げようとしています。私はInside the JVM book をオンラインで読んでいますが、理解できない紛らわしい抽象概念が 1 つあります。それは、Constant Pool です。ここに本からの抜粋があります:

ロードする型ごとに、Java 仮想マシンは定数プールを格納する必要があります。定数プールは、リテラル (文字列、整数、および浮動小数点定数) と、型、フィールド、およびメソッドへのシンボリック参照を含む、型によって使用される定数の順序付けられたセットです。定数プールのエントリは、配列の要素と同じように、インデックスによって参照されます。型によって使用されるすべての型、フィールド、およびメソッドへのシンボリック参照を保持するため、定数プールは Java プログラムの動的リンクにおいて中心的な役割を果たします。

上記および CP 全般についていくつか質問があります。

  1. CP.classは各タイプのファイルに配置されていますか?
  2. 著者は「シンボリック参照」とはどういう意味ですか?
  3. コンスタントプールの目的は何ですか?簡単な英語で?
4

5 に答える 5

93

定数プールは、.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定数プールへの参照は次のとおりです。#2System.outフィールドへのシンボリック参照、#3Hello, world!文字列、およびメソッド#4へのシンボリック参照PrintStream.println(String)です。

ご覧のとおり、シンボリック参照は単なる名前ではありません。たとえば、メソッドへのシンボリック参照には、そのパラメーター ( Ljava/lang/String;) と戻り値の型 ( Vmeans void) に関する情報も含まれています。

そのクラスに対して実行することにより、クラスの定数プールを検査できますjavap -verbose

于 2012-04-18T13:25:33.640 に答える
78

図を使用してフレームがどのように構築されているかを理解すると役立つと思います。

ここに画像の説明を入力

フレームは、オペランド (演算命令) が存在する場所であり、動的リンクが発生する場所です。いわば、定数プールを使用してクラスとそのメンバーを追跡する簡単な方法です。

各フレームには、ランタイム定数プールへの参照が含まれています。参照は、そのフレームで実行されているメソッドのクラスの定数プールを指します。このリファレンスは、動的リンクをサポートするのに役立ちます。

通常、C/C++ コードはオブジェクト ファイルにコンパイルされ、複数のオブジェクト ファイルがリンクされて、実行可能ファイルや dll などの使用可能なアーティファクトが生成されます。リンク段階で、各オブジェクト ファイル内のシンボリック参照は、最終的な実行可能ファイルに関連する実際のメモリ アドレスに置き換えられます。Java では、このリンク フェーズは実行時に動的に行われます。

Java ファイルがコンパイルされると、変数とメソッドへのすべての参照が、シンボリック参照としてクラスの定数プールに格納されます。シンボリック参照は、物理メモリの場所を実際に指す参照ではなく、論理参照です。

詳細については、 James Blooms JVM Internalsへのリンクを参照してください。

于 2013-12-03T17:24:19.280 に答える
9

コンスタントプールの目的は何ですか?簡単な英語で?

CP は、冗長性を減らすために非常に一意の定数値が格納されるメモリ領域です。

System.err.println("Hello");
System.out.println("Hello");

CP には String オブジェクト "Hello" が 1 つだけあり、コンパイラは両方の行を同じ参照に置き換えます。.class ファイルには、Hello 文字列が 1 つだけ含まれています。(他の種類も同様)。

CP はタイプごとに .Class ファイルにありますか?

はい、こちらをご覧ください: http://en.wikipedia.org/wiki/Java_class_file

于 2012-04-18T13:15:23.420 に答える