実際には、唯一のインスタンスが 2 回参照されていることがわかります。一番左の列の値が異なることに注意してください。同じインスタンスを指している異なるレジスタまたはスタック フレームの異なる部分である可能性があります。
私の経験では、これはかなり頻繁に発生します (特にデバッグ ビルドの場合)。!dsoオブジェクトを見つけるのに役立ちます。その場合、重要な列は実際の参照を保持する Object 列です。
たとえば、デバッガーから上記の例を実行し、Main にブレーク ポイントを配置するとdso、Main メソッドが戻る直前に出力が次のようになります。
0:000> !dso
OS Thread Id: 0x1944 (0)
ESP/REG Object Name
eax 0240b2e0 TestApp.Program+MyClass
ecx 0240b2e0 TestApp.Program+MyClass
0014F224 0240b2d0 System.Object[] (System.String[])
0014F3CC 0240b2d0 System.Object[] (System.String[])
0014F400 0240b2d0 System.Object[] (System.String[])
ご覧のとおり、C# ソースには参照が 1 つしかないにもかかわらず、eaxとレジスタの両方がインスタンスへの参照を保持しています。ecx
Main の JIT コンパイル コードを見ると、次のようになります。
0:000> !u 00200070
Normal JIT generated code
TestApp.Program.Main(System.String[])
Begin 00200070, size 46
C:\dev2010\TestApp\TestApp\Program.cs @ 33:
>>> 00200070 55 push ebp
00200071 8bec mov ebp,esp
00200073 83ec14 sub esp,14h
00200076 33c0 xor eax,eax
00200078 8945f4 mov dword ptr [ebp-0Ch],eax
0020007b 8945f8 mov dword ptr [ebp-8],eax
0020007e 894dfc mov dword ptr [ebp-4],ecx
00200081 833d3c31150000 cmp dword ptr ds:[15313Ch],0
00200088 7405 je 0020008f
0020008a e8c05ac268 call clr!JIT_DbgIsJustMyCode (68e25b4f)
0020008f 33d2 xor edx,edx
00200091 8955f0 mov dword ptr [ebp-10h],edx
00200094 90 nop
C:\dev2010\TestApp\TestApp\Program.cs @ 35:
00200095 b960391500 mov ecx,153960h (MT: TestApp.Program+MyClass)
0020009a e8811ff4ff call 00142020 (JitHelp: CORINFO_HELP_NEWSFAST)
0020009f 8945ec mov dword ptr [ebp-14h],eax
002000a2 8b4dec mov ecx,dword ptr [ebp-14h]
002000a5 ff158c391500 call dword ptr ds:[15398Ch] (TestApp.Program+MyClass..ctor(), mdToken: 06000003)
002000ab 8b45ec mov eax,dword ptr [ebp-14h]
002000ae 8945f0 mov dword ptr [ebp-10h],eax
C:\dev2010\TestApp\TestApp\Program.cs @ 36:
002000b1 90 nop
002000b2 8be5 mov esp,ebp
002000b4 5d pop ebp
002000b5 c3 ret
指示に注意してくださいcall 00142020。これにより、のインスタンスが作成され、レジスタMyClass内の参照が返されます。eaxその後、参照は に保存されdword ptr [ebp-14h]ます。
次の命令は、に格納されている値を読み取り、その値dword ptr [ebp-14h]をレジスターに格納します。この値はecx、コンストラクターへの呼び出しの入力として使用されますcall dword ptr ds:[15398Ch] (TestApp.Program+MyClass..ctor(), mdToken: 06000003)。
dsoこれは、この場合に参照を 2 回リストする理由を説明しています。ただし、デバッグ時にこれについて詳しく説明する必要はほとんどありません。