1

コンパイル時にアドレスバインディングが不可能な場合、ロード/リンクまたは実行時に、相対 (またはおそらくそれらをリロケータブルアドレスと呼ぶことができます) アドレスを実際の物理アドレスに関連付けるために行われます。さらに、CPU は物理アドレスをバインドする前に、これらの相対アドレスを論理アドレスに変換します。

論理から物理への変換は、私にとって既知の概念です。しかし、私はそれらの相対アドレス指定について混乱しました(AFAIK、コンパイラーによってゼロに対して相対的に与えられた/割り当てられたので、彼らは相対と呼びました)。(バイトコードで)どの相対アドレスが使用されているのか、またはそれらが本当に必要なのか、それとも論理アドレスと同一であるかさえわかりませんか?

4

3 に答える 3

1

オブジェクトのメモリ アドレスを取得することは、Java 内では実際には無意味です。JVM がそのすべてを管理しているためです。

言い換えると、JVM は、オブジェクトが適切な場所に「配置」されます。また、「移動」することもできます。たとえば、ガベージ コレクション中。

言い換えれば、Java プログラマーは気にしません。そして、あなたが気にするなら; これについてあなたができることは何もありません。

于 2016-08-16T14:40:02.527 に答える
1

あなたは多くの概念を混同しています。相対アドレスは、ベースアドレスを絶対アドレスに変換する必要があるアドレスです。その変換は、さまざまな方法で発生する可能性があります。1 つの方法はロード時に変換することですが、メモリ位置にアクセスする必要があるときに計算を行う相対アドレス指定を本質的にサポートする CPU 命令と一緒に使用することもできます。

オペレーティング システムが仮想メモリをサポートしている場合、通常のプロセス内で使用されるすべてのアドレスは、相対参照か絶対参照かに関係なく、論理アドレスです。論理アドレスから物理アドレスへの変換は、アプリケーションの範囲外であり、質問で言及している他の概念とは無関係です。

クラス ファイル形式は、メモリ位置に関しては機能しません。

その上位レベルで「絶対」および「相対」という用語を適用する場合、実際のインデックスを識別するためにベース インデックスを必要としないため、定数プール インデックスは絶対的です。それでも、ロードされたファイル内のメモリ位置を見つけたい場合は、クラス ファイルがロードされたアドレスを使用する必要があるだけでなく、定数プール全体を目的のアイテムまで解析する必要もあります。異なるバイトサイズ。そのため、アイテムは通常まったく検索されません。代わりに、プール全体が 1 回のパスで一定の項目サイズを持つ JVM 固有の表現に変換され、その後、JVM はそのテーブルのエントリを検索する可能性があります。これはクラス ファイルのメモリ位置とは無関係です。

バイトコード命令内では、絶対位置を取得するために現在の命令の位置を追加する必要がある相対オフセットが使用されますが、これが質問で指定された概念に適合しないことに注意してください。絶対位置は依然として命令シーケンス内の位置であるため、アドレスについて話すときはコードのメモリ位置に相対的です。さらに、「コンパイル時にバインディングができない」ため、相対オフセットは使用されず、結果の絶対位置はコンパイル時に認識されます。Java バイトコード命令セットは、相対オフセットを使用してよりコンパクトなコードを可能にするように定義されています。命令セットの観点からは、本質的に相対アドレッシングをサポートしていると言えます。JVM が実際にその実行をどのように実装するかは、JVM 次第です。

JVM のネイティブ コード生成について言及したので、JVM がネイティブ コードを生成するとき、コードのターゲット アドレスを認識し、適切な相対アドレスまたは絶対アドレスの使用を自由に決定できます。

すでに述べたように、上記のすべてが 1 つのプロセス内で発生するため、オペレーティング システムが仮想メモリを使用する場合、すべて論理アドレスの観点から、たとえば MMU を介してオペレーティング システムによって適応される可能性があります。これらの概念は無関係です。

于 2016-08-18T16:50:14.097 に答える
1

Java バイトコードは、ネイティブ マシン コードよりもはるかに高い抽象化レベルで動作します。メモリ アドレスの概念はまったくありません。メソッドはシンボリックに参照されます。

Java バイトコードを考える最も簡単な方法は、Java 言語の初期バージョンと事実上 1:1 であるということです。コンパイラは、ローカル変数を数値インデックスに変換したり、制御フローを goto に変換したりするなどの処理を行いますが、ほとんどの場合、元のコードと非常によく似ています。

JVM は、実行時にバイトコードをネイティブ コードに解釈またはコンパイルする役割を果たします。

于 2016-08-16T14:38:18.713 に答える