2017-02-18 35 views
2

.NET Frameworkを使用してオブジェクトがメモリに格納される仕組みを理解しようとしています。オブジェクトはどのようにメモリに保存されていますか?

personクラスを考える:、

  • まず:私はタイプPersonの開始変数がメモリ内に次のような構造を持っていると考えている

    public class Person 
    { 
        public string name { get; set; } 
    
        public int age { get; set; } 
    } 
    

    を: Person Memory Structure

    質問私の理解の主な/明白な欠陥は何ですか? (私はほぼ確実ですが、私が記述している方法でオブジェクトを処理するのが効率的ではないように思えます;特にnameポインタが文字列メンバのcharコレクションを指す方法で)

  • 第2に、クラスの値型メンバ(IE Age)は、オブジェクト自体(オブジェクトと同じメモリアドレス内)に格納されているか、オブジェクトが自身のアドレスを割り当てられていますか? (私のダイアグラムのような)

  • 上記の質問に似ていますが、参照型メンバーの場合、オブジェクトはポインタへのポインタを保持していますか?私のPersonクラスのメンバーがプロパティではなくフィールドであれば違いがありますか?

アップデート:私は今正しいと信じているスイーパー&ティムからの回答に基づいて更新図。

Correct Diagram

注:ポインタは、このコードを管理されているように参照するように変更します。

答えて

1

私は最も簡単なツー答え質問から始めましょう:私のPersonクラスのメンバーは、フィールドではなくプロパティであれば、それは違いを生むだろう

いいえ。コード内のプロパティは、単なる構文的な砂糖です。コードがコンパイルされると、{ get; set; }のこれらのプロパティは、ゲッターとセッターでフィールドに変換されます。

私の理解に大きな欠点がありますか?

はい。私は以下の質問に答えるときにそれらを言及するでしょう。

第2に、クラス(IE Age)の値型メンバーの場合、オブジェクト自体(オブジェクトと同じメモリアドレス内)に格納されているのか、独自のアドレスが割り当てられるのでしょうか?オブジェクトはそれを指していますか?(私のダイアグラムのような)

あなたの最初のステートメントは正しいです。値の型はオブジェクト内に格納されます。 Personオブジェクトのポインタがintを指していません。つまり、あなたの図は間違っています。

参照型メンバーの場合、オブジェクトはポインタへのポインタを保持していますか? (I.E私の図の中のcharコレクションを参照する名前ポインタ)

この場合、char[]は気付いたように参照型です。しかし、それは実際に値の種類であるcharの束を保持しています。だから、文字はAgePersonに格納されているように、char配列内に格納されます。一方、これがstring[]であれば、文字列オブジェクトを指すポインターを含む配列を指すポインターがあります。これはまた、ダイアグラムが間違っていることを意味します。

+0

ありがとうございます。私はあなたと私は今正しいと思うティムの答えに基づいて更新された図を追加しましたか? – KidCode

+0

@KidCodeはいそうです。 – Sweeper

2

.netの世界では、ポインタは管理されていないメモリを指し、オブジェクト参照は管理オブジェクトを参照します。オブジェクトはいつでもガベージコレクタによって移動される可能性があります。そのため、ポインタは警告なしで破棄されます。概念は同じですが、安全ではないC#コードでポインタを持つことができるので、違いがあります。オブジェクトへのポインタをつかんでそのオブジェクトが動くと、ポインタは任意のメモリ空間を指します。ただし、オブジェクト参照は保持されます。

年齢の問題に。これは、オブジェクト自体に格納され、構造体内の32ビットを占めています。int32への参照/ポインタではありません

参照型メンバの場合、ポインタは概念的にはポインタと同じです。 64ビットの空間(アーキテクチャに応じて32)を使用しますが、上記のように多少異なります。

最後に、匿名プロパティは実際には隠しフィールドと、これらのフィールドを設定して返す自動書き込みコードを作成しています。ストレージは同じですが、フィールドで直接アクセスするのではなく、プロパティを使用してアクセスするためのコストはごくわずかです。

3

いくつか間違いがあります。 intメンバーが間違っています。これは値タイプです。ポインタがないので、Personオブジェクトのストレージに含まれ、4バイトかかります。 という名前のオブジェクト参照も正しく表示されません。これはStringオブジェクトを指しています。文字列の文字列は、文字列の格納場所に含まれており、intのように格納されています。別の言い方をすれば、文字列オブジェクト記憶域のサイズは可変であり、文字を格納するのに必要な大きさである。

Personオブジェクトのメンバーにアクセスすると、2つのポインタだけを間接的に参照することになり、効率的になります。

はい、タイプPersonの変数はポインタだけを格納します。 GCは、ヒープを圧縮するときにそれを更新します。

プロパティは実行時に存在しないため、コンパイラによって提供される抽象です。最も一般的には、getterメソッドとsetterメソッドを自分で指定しない限り、コンパイラはそのフィールドを割り当てます。あなたの図の中の「名前」と「年齢」は実際にはフィールドになっていますが、別の名前になります。

関連する問題