13

クラスが次のオブジェクトをインスタンス化すると、メモリ内で何が起こりますか?

public class SomeObject{

    private String strSomeProperty;

    public SomeObject(String strSomeProperty){
        this.strSomeProperty = strSomeProperty;
    }
    public void setSomeProperty(String strSomeProperty){
        this.strSomeProperty = strSomeProperty;
    }
    public String getSomeProperty(){
        return this.strSomeProperty;
    }
}

クラスでSomeClass1

SomeObject so1 = new SomeObject("some property value");

クラスでSomeClass2

SomeObject so2 = new SomeObject("another property value");

新しくインスタンス化されたオブジェクトとそのプロパティにメモリがどのように割り当てられるか?

4

3 に答える 3

12

それを見てみましょう:

SomeObject so1 = new SomeObject("some property value");

... 新しい文字列を作成しているため、実際には見た目よりも複雑です。次のように考えるとわかりやすいかもしれません。

String tmp = new String("some property value");
SomeObject so1 = new SomeObject(tmp);
// Not that you would normally write it in this way.

(完全に正確に言うと、これらは実際には同等ではありません。オリジナルでは、「新しい文字列」はコンパイル時に作成され、.class イメージの一部です。これはパフォーマンス ハックと考えることができます。)

そのため、最初に JVM が文字列にスペースを割り当てます。通常、String 実装の内部構造については知らないか気にしないので、「何らかのプロパティ値」を表すためにメモリのチャンクが使用されていることを信頼してください。また、文字列への参照を含むメモリが一時的に割り当てられています。2 番目の形式では、明示的に呼び出されtmpます。元の形式では、Java は名前を付けずに処理します。

次に、JVM は新しい SomeObject にスペースを割り当てます。これは、Java の内部簿記用のわずかなスペースであり、オブジェクトの各フィールド用のスペースです。この場合、フィールドは 1 つだけstrSomePropertyです。

これstrSomePropertyは単なる String への参照であることに注意してください。今のところ、null に初期化されます。

次に、コンストラクターが実行されます。

this.strSomeProperty = strSomeProperty;

これは、文字列への参照strSomePropertyをフィールドにコピーするだけです。

最後に、オブジェクト参照用のスペースが割り当てられますso1。これは、SomeObject への参照で設定されます。

so2まったく同じように機能します。

于 2008-11-26T15:17:24.770 に答える
7

Determining Memory Usage in Java by Dr. Heinz M. Kabutz が正確な回答と、メモリ使用量を計算するプログラムを提供しています。関連部分:

  1. クラスは少なくとも 8 バイトを使用します。したがって、 new Object(); と言うと ヒープに 8 バイトを割り当てます。
  2. 各データ メンバーは、8 バイトを使用する long および double を除いて、4 バイトを使用します。データ メンバが 1 バイトの場合でも、4 バイトを使用します。さらに、使用されるメモリ量は 8 バイト ブロックで増加します。したがって、1 バイトを含むクラスがある場合、クラスに 8 バイト、データに 8 バイト、合計 16 バイトを使用します (うめき声!)。
  3. 配列はもう少し賢いです。プリミティブは配列にパックされるため、バイトの配列がある場合、それぞれが 1 バイトを占有します (すごい!)。もちろん、メモリ使用量は 8 バイト ブロック単位で増加します。

コメントで指摘されているように、文字列はインターンできるため、特殊なケースです。それらが占めるスペースについても同じように推論できますが、同じ文字列の複数のコピーのように見えるものは、実際には同じ参照を指している可能性があることに注意してください。

于 2008-11-26T17:07:54.253 に答える
3

覚えておくべきポイント:

  1. メソッドが呼び出されると、スタックの一番上にフレームが作成されます。
  2. メソッドの実行が完了すると、制御の流れが呼び出し元のメソッドに戻り、対応するスタック フレームがフラッシュされます。
  3. ローカル変数はスタックに作成されます。
  4. インスタンス変数はヒープ内に作成され、それらが属するオブジェクトの一部です。
  5. 参照変数はスタックに作成されます。

参照: http://www.javatutorialhub.com/java-stack-heap.html

于 2012-08-28T09:38:59.753 に答える