0

この質問は単に興味がなく、オブジェクト指向言語でのメモリ管理について何かを理解しようとしているだけです。1つの言語に固有のものではありませんが、一般的な原則として理解したいと思います。

私が知りたいのは、オブジェクト参照の定義が、その参照のインスタンスと比較してどのように格納されるかです。

インスタンス化せずに、たとえばJavaでOOソースコードを定義してオブジェクト化する場合:

String s;

これはどのように保存されますか?この定義のメモリ使用量は、オブジェクトが実際にインスタンス化されたときとどのように異なりますか。

s = new String("abc");

?メモリの割り当て方法に関してすべてのオブジェクト指向言語に適用される一般的な原則はありますか、または異なる言語の実装者はメモリを割り当てるために異なる手法を使用しますか?

4

2 に答える 2

0

String のような参照を宣言するときは通常です。int 、 float と同じように通常の変数として作成されますが、このタイプの変数はメモリアドレスを保持します (C 言語のポインターと同様の概念 )。、ヒープにオブジェクトを作成し、そのアドレスを参照変数sに割り当てます。

于 2012-10-08T06:41:52.973 に答える
0

Java バイト コードでは、すべてのオブジェクトはオブジェクトとして格納されます。必要に応じて、明示的な型チェックが追加されます。たとえば、このJava関数

public Integer getValue(Object number){
  int i = ((Number) number).toInt();
  return new Integer(i);
}

次のようなバイトコードに変換されます。

(accepts java.lang.Object, returns java.lang.Integer)

-read the first argument as an Object
-if the value is not a Number, raise an exception
-call the virtual method toInt(java.lang.Integer) of the value
    and remember the int result
-use the value as an int argument
-instantiate a new java.lang.Integer
-call the constructor(int) of java.lang.Integer on the new number,
    getting an Object back
[since the declared return value of Number.toInt is the same
    as the return value of our function, no type checking is needed]
-return the value

そのため、未使用の変数の型はコンパイラによって取り除かれます。パブリック フィールドとプロテクト フィールドの型は、そのクラスと共に格納されます。

オブジェクトの実行時の型は、オブジェクトと共に格納されます。C++ では、仮想メソッド テーブルへのポインターです。Java では、ロードされたすべてのクラスのテーブルへの 16 ビット インデックスとして存在します。

Java クラス ファイルは、すべての依存クラスのインデックスを同様のテーブルに格納します。ここにはクラス名のみが格納されます。すべてのフィールドの説明は、このテーブルを指します。

したがって、あなたが書くときString s = new String("abc")(またはさえString s = "abc")、あなたのクラスは以下を保存します:

  • 依存関係の表にあるクラス java.lang.String に依存しています。
  • 文字列リテラルの表の「abc」
  • ID で文字列リテラルをロードするメソッド
  • (最初のケースでは) 最初の依存クラス (String) を引数として、最初の依存クラス (String) のコンストラクターを呼び出すメソッド。
  • コンパイラは、新しい String を String 変数に格納することが安全であることを証明できるため、型チェックをスキップします。

クラスは、参照されるとすぐにロードすることも、最初に使用するまでロードすることもできます (この場合、依存するクラスとクラス内の ID によって参照されます)。最近は後者が多いと思います。

クラスがロードされると:

-its class loader is asked to retreive the class by its name.
-(in the case of the system loader) the class loader looks
    for the corresponding file in the program JAR, in the system library
    and in all libraries referenced.
-the byte stream is then decoded into a structure in memory
-(in the case of early loading) all dependent classes are loaded recursively
    if not already loaded
-it is stored in the class table
-(in the case of late loading) its static initialiser is run
    (possibly loading more classes in the process).

C++ では、すべてのユーザー クラスとほとんどのライブラリが単なる仮想メソッド テーブルと対応するメソッドとしてプログラムに格納されるため、クラスのロードは行われません。すべてのシステム関数 (クラスではない) は、DLL (Windows の場合) または同様のファイルに格納し、実行時にライブラリによってロードできます。明示的な型キャストによって型チェックが暗示される場合、仮想メソッド テーブルで実行されます。また、C++ にはしばらくの間、型チェック メカニズムがなかったことにも注意してください。

于 2012-10-08T08:41:33.790 に答える