「マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
LOHの問題によってGen2の断片化に起因するメモリリークが発生することもある(.NET3.5までの問題)。
久しぶりに使ったので手順などをメモ(幾つか補足も記載)。
※ 同様の操作をマネージ・ダンプに対して行う事もできる。
以下はSOSデバッガ拡張コマンドの実行例。
.load sos マネージのみのデバッグ中は、SOS は使用できません。 SOS を読み込むには、プロジェクト プロパティのアンマネージ デバッグを有効にしてください。
拡張 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\sos.dll は読み込まれました
!DumpHeap [<-stat>] [-min <size>] [-max <size>] [-thinlock]~ [-mt <Method Table address>] [-type <partial type name>] [start[end]]
!DumpHeap -Type Class1 PDB symbol for mscorwks.dll not loaded Address MT Size 013ac060 009e71fc 20 total 1 objects Statistics: MT Count TotalSize Class Name 009e71fc 1 20 WindowsFormsApplication1.Class1 Total 1 objects
!DumpObj <Object address>
!DumpObj 013ac060 Name: WindowsFormsApplication1.Class1 MethodTable: 009e71fc EEClass: 00f01fb8 Size: 20(0x14) bytes Fields: MT Field Offset Type VT Attr Value Name 79332d70 4000006 4 System.Int32 1 instance 9 a 79332d70 4000007 8 System.Int32 1 instance 9 b 79332d70 4000008 c System.Int32 1 instance 9 c 79332d70 4000009 24 System.Int32 1 static 9 x 79332d70 400000a 28 System.Int32 1 static 9 y 79332d70 400000b 2c System.Int32 1 static 9 z
DumpObj?に指定したオブジェクトのアドレスから
メモリ情報([メモリ] ウィンドウ)を確認すると
メンバ変数の情報を確認することができる。
!DumpClass <EEClass address>
!DumpClass 00f01fb8 Class Name: WindowsFormsApplication1.Class1 Parent Class: 790c3ef0 Module: 009e2c5c Method Table: 009e71fc Vtable Slots: 4 Total Method Slots: 6 Class Attributes: 100001 NumInstanceFields: 3 NumStaticFields: 3 MT Field Offset Type VT Attr Value Name 79332d70 4000006 4 System.Int32 1 instance a 79332d70 4000007 8 System.Int32 1 instance b 79332d70 4000008 c System.Int32 1 instance c 79332d70 4000009 24 System.Int32 1 static 9 x 79332d70 400000a 28 System.Int32 1 static 9 y 79332d70 400000b 2c System.Int32 1 static 9 z
こちらでは、インスタンス変数の値は表示されない。
また、上記のフィールド情報はilasmを使用して確認できるらしいが、情報を確認できず。
!DumpModule <Modul address>
!DumpModule 009e2c5c Attributes: PEFile Assembly: 001b2478 LoaderHeap: 00000000 TypeDefToMethodTableMap: 009e00c0 TypeRefToMethodTableMap: 009e00dc MethodDefToDescMap: 009e0194 FieldDefToDescMap: 009e01d4 MemberRefToDescMap: 009e0204 FileReferencesMap: 009e02dc AssemblyReferencesMap: 009e02e0 MetaData start address: 00402440 (4084 bytes)
インスタンス └メソッドテーブル ┬ EEClass ─ BaseClass ├ MT of BaseClass └ Module ┬ Field Descriptor Map └ TypeDef To Method Table Map
!DumpMT -md <Method Table address>(-mdを付与しないと一覧情報が出力されない)
!DumpMT -md 009e71fc EEClass: 00f01fb8 Module: 009e2c5c Name: WindowsFormsApplication1.Class1 mdToken: 02000006 BaseSize: 0x14 ComponentSize: 0x0 Number of IFaces in IFaceMap: 0 Slots in VTable: 6 -------------------------------------- MethodDesc Table Entry MethodDesc JIT Name 79286aa0 79104944 PreJIT System.Object.ToString() 79286ac0 7910494c PreJIT System.Object.Equals(System.Object) 79286b30 7910497c PreJIT System.Object.GetHashCode() 792f7510 791049a0 PreJIT System.Object.Finalize() 009ec160 009e71e4 JIT WindowsFormsApplication1.Class1..ctor() 009ec168 009e71f0 JIT WindowsFormsApplication1.Class1..cctor()
!DumpHeap -stat total 10311 objects Statistics: MT Count TotalSize Class Name ・・・ 009e6c90 1 20 WindowsFormsApplication1.Class1 ・・・ 009e5e50 1 332 WindowsFormsApplication1.Form1
!DumpHeap -mt 009e5e50 Address MT Size 013bd8f4 009e5e50 332 total 1 objects Statistics: MT Count TotalSize Class Name 009e5e50 1 332 WindowsFormsApplication1.Form1 Total 1 objects
!gcroot 013bd8f4 Note: Roots found on stacks may be false positives. Run "!help gcroot" for more info. ebx:Root:013be34c(System.Windows.Forms.Application+ThreadContext)-> 013bd8f4(WindowsFormsApplication1.Form1) esi:Root:013e0b2c(System.Windows.Forms.Application+ComponentManager+ComponentHashtableEntry)-> 013be34c(System.Windows.Forms.Application+ThreadContext) edi:Root:013eb4a0(System.Collections.Hashtable+HashtableEnumerator)-> 013e0b2c(System.Windows.Forms.Application+ComponentManager+ComponentHashtableEntry) Scan Thread 0 OSTHread 1a30 ESP:12f358:Root:013be34c(System.Windows.Forms.Application+ThreadContext)-> 013e0b2c(System.Windows.Forms.Application+ComponentManager+ComponentHashtableEntry) ESP:12f360:Root:013e0ae4(System.Windows.Forms.Application+ComponentManager)-> 013be34c(System.Windows.Forms.Application+ThreadContext) ・・・ 013dc328(Microsoft.Win32.UserPreferenceChangedEventHandler)-> 013bd8f4(WindowsFormsApplication1.Form1) DOMAIN(00159EE0):HANDLE(Pinned):9c13ec:Root:02333250(System.Object[])-> 013be278(System.Collections.Hashtable)-> 013be2b0(System.Collections.Hashtable+bucket[])-> 013be34c(System.Windows.Forms.Application+ThreadContext)
!eeheap -gc Number of GC Heaps: 1 generation 0 starts at 0x01331018 generation 1 starts at 0x0133100c generation 2 starts at 0x01331000 ephemeral segment allocation context: none segment begin allocated size 01330000 01331000 013ebff4 0x000baff4(765940) Large object heap starts at 0x02331000 segment begin allocated size 02330000 02331000 02336de8 0x00005de8(24040) Total Size 0xc0ddc(789980) ------------------------------ GC Heap Size 0xc0ddc(789980)
!objsize 013bd8f4 sizeof(013bd8f4) = 13420 ( 0x346c) bytes (WindowsFormsApplication1.Form1) ※ 単体:332、参照先を含める:13420
!finalizequeue SyncBlocks to be cleaned up: 0 MTA Interfaces to be released: 0 STA Interfaces to be released: 0 ---------------------------------- generation 0 has 360 finalizable objects (001e7090->001e7630) generation 1 has 0 finalizable objects (001e7090->001e7090) generation 2 has 0 finalizable objects (001e7090->001e7090) Ready for finalization 0 objects (001e7630->001e7630) Statistics: MT Count TotalSize Class Name 7b2252dc 1 16 System.Windows.Forms.Control+FontHandleWrapper 7b226088 1 20 System.Windows.Forms.ApplicationContext 79321428 1 20 Microsoft.Win32.SafeHandles.SafePEFileHandle 7ae3ca3c 1 24 System.Drawing.Bitmap 7b226160 1 28 System.Windows.Forms.Cursor ・・・ 009e5e50 1 332 WindowsFormsApplication1.Form1 7b2238c4 26 728 System.Windows.Forms.Internal.WindowsGraphics 7b21a930 20 960 System.Windows.Forms.Internal.WindowsPen 7932a41c 87 1392 System.WeakReference 7b223a00 26 1872 System.Windows.Forms.Internal.DeviceContext Total 360 objects
* e !clrstackで、全てのマネージスレッドとスタックトレースし、ファイナライザスレッドのハングを確認する。
~* e !clrstack OS Thread Id: 0x1a30 (0) ESP EIP 0012f32c 7c94e514 [InlinedCallFrame: 0012f32c] System.Windows.Forms.UnsafeNativeMethods.WaitMessage() 0012f328 7b1d8ed8 System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32, Int32, Int32) 0012f3c4 7b1d89c7 System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext) 0012f418 7b1d8811 System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext) 0012f448 7b195921 System.Windows.Forms.Application.Run(System.Windows.Forms.Form) 0012f45c 00f300ae WindowsFormsApplication1.Program.Main() 0012f688 79e71b4c [GCFrame: 0012f688] OS Thread Id: 0x1a44 (1) Unable to walk the managed stack. The current thread is likely not a managed thread. You can run !threads to get a list of managed threads in the process OS Thread Id: 0x16c8 (2) Failed to start stack walk: 80004005 OS Thread Id: 0xa14 (3) Unable to walk the managed stack. The current thread is likely not a managed thread. You can run !threads to get a list of managed threads in the process OS Thread Id: 0x11fc (4) Unable to walk the managed stack. The current thread is likely not a managed thread. You can run !threads to get a list of managed threads in the process
!Threads -special ThreadCount: 2 UnstartedThread: 0 BackgroundThread: 1 PendingThread: 0 DeadThread: 0 Hosted Runtime: no PreEmptive GC Alloc Lock ID OSID ThreadOBJ State GC Context Domain Count APT Exception 0 1 1a30 00161b98 6020 Enabled 013eb4c4:013ebfe8 00159ee0 0 STA 2 2 16c8 0016e360 b220 Enabled 00000000:00000000 00159ee0 0 MTA (Finalizer) OSID Special thread type 1 1a44 DbgHelper 2 16c8 Finalizer
WinDbgとSilverlightをインストールしておく。
以下WinDbgにてSilverlightのダンプファイルから、オブジェクト数を確認する手順の例。
アタッチ先を「iexplore.exe」などに設定すれば、ライブ・デバックも可能であるもよう。
.load C:\Program Files\Microsoft Silverlight\4.1.10329.0\sos.dll※パスは環境(インストール・バージョン、インストール先)に応じて修正してください
!dumpheap -stat
!dumpheap -stat -type XXXXXXX
Silverlight Toolkitにメモリリークの問題があります。
We encountered this bug too, but took a slightly different tact -- we used a weak event listener pattern.
if (null != _rootVisual) { // Ideally, this would use AddHandler(MouseMoveEvent), but MouseMoveEvent doesn't exist _rootVisual.MouseMove += new MouseEventHandler(HandleRootVisualMouseMove); }
if (null != _rootVisual) { var rootVisual = _rootVisual; // Use a weak event listener. var rootVisualMouseMoveListener = new WeakEventListener<ContextMenu, object, MouseEventArgs>( this ); rootVisualMouseMoveListener.OnEventAction = ( instance, source, eventArgs ) => instance.HandleRootVisualMouseMove( source, eventArgs ); rootVisualMouseMoveListener.OnDetachAction = ( weakEventListener ) => rootVisual.MouseMove -= weakEventListener.OnEvent; rootVisual.MouseMove += rootVisualMouseMoveListener.OnEvent; }
ここの「we used:」が修正コード。
Visual Studio2015 Enterprise Edition ではマネージ メモリの分析機能が
強化されており、!DumpHeap? コマンドで実現できることに近い内容が確認できる。
"マネージ型レポート"
.NET Framework アプリケーションのデバッグに有用
(ただし、サポートは提供されておらずドキュメントや公開情報も少ない状況)
.load "C:\\Psscor4\\x86\\x86\\psscor4.dll" !psscor4.help
.load mex.dll !mex.help