C#におけるオブジェクト参照とメモリ管理の可視化
このスクリーンショットは、C#コードのメモリグラフを視覚化するツールを使って、Player
オブジェクトのメモリの状態を示しています。以下に、各部分の説明と分析を示します。
ツールを使った解析
![](https://soft-rime.com/wp-content/uploads/2024/07/スクリーンショット-2024-07-17-3.57.19-1024x327.png)
Player player1 = new Player();
ChangeObj(player1);
Inspect.MemoryGraph(player1);
Inspect.Stack(player1);
Inspect.Heap(player1);
void ChangeObj(Player player)
{
player = new Player();
Inspect.MemoryGraph(player);
Inspect.Stack(player);
Inspect.Heap(player);
}
class Player
{
}
解説
Player player1 = new Player();
player1
変数が新しいPlayer
オブジェクトを指すように初期化されています。
ChangeObj(player1);
player1
を引数としてChangeObj
メソッドが呼び出されます。ここで、player
はplayer1
のコピーです。
Inspect.MemoryGraph(player1);
、Inspect.Stack(player1);
、Inspect.Heap(player1);
player1
のメモリ状態を表示しています。この時点でのメモリグラフとスタック、ヒープの状態が右側に表示されています。
void ChangeObj(Player player)
player
変数に新しいPlayer
オブジェクトを割り当てています。この操作はメソッド内でのみ有効で、player1
には影響しません。
Inspect.MemoryGraph(player);
、Inspect.Stack(player);
、Inspect.Heap(player);
ChangeObj
メソッド内で新しく割り当てられたplayer
のメモリ状態を表示しています。
メモリの状態
右側の結果表示部分には、player1
とplayer
のメモリ状態が示されています。以下にそれぞれの説明をします。
player1
- スタックには
player1
の参照があり、それがヒープ上のPlayer
オブジェクトを指しています。 - ヒープには、
0x179814AF7B8
アドレスにPlayer
オブジェクトが存在します。
- スタックには
ChangeObj
メソッド内のplayer
ChangeObj
メソッド内で新しいPlayer
オブジェクトが割り当てられています。player
は新しい0x179814AF7A0
アドレスのPlayer
オブジェクトを指しています。
結論
ChangeObj
メソッドは、引数として渡されたplayer1
の参照を受け取りますが、メソッド内で新しいPlayer
オブジェクトを作成しても、元のplayer1
には影響しません。これが、メソッドの外でplayer1
が最初に作成されたPlayer
オブジェクトを指し続けている理由です。
このメモリの可視化は、参照型の変数がどのように動作するかを理解するのに非常に有用です。特に、メソッド内で新しいオブジェクトを割り当てても、元の参照は変更されないという点が重要です。
ディスカッション
コメント一覧
まだ、コメントがありません