OutOfMemoryException (OOM)。.NET CLR Memory 類別 (% Time in GC, Allocated Bytes/sec, Gen 0/1/2 Collections, LOH Size, Promoted Memory 等)。.loadby sos mscorwks,指令 !dumpheap -stat, !gcroot, !finalizequeue, !eeheap -gc, !threads 等。VM Size (Private Bytes) 趨勢判斷洩漏。.dump /ma file.dmp,離線分析生產環境問題。| 計數器 | 關注重點 |
|---|---|
| % Time in GC | > 50% 需調查;< 10% 通常無需優化。 |
| Allocated Bytes/sec | 配置速率高 → 頻繁 GC。注意計數器只在 GC 時更新。 |
| Gen 0/1/2 Collections | 理想比例:10 次 Gen1 : 1 次 Gen2。Gen2 過多代表物件過早晉升。 |
| Promoted Memory (Gen 0/1) | Gen1 晉升率過高 → 「中年危機」:物件存活夠久晉升 Gen2,但又不夠久留在 Gen2,增加 Gen2 GC 成本。 |
| # Total committed/reserved Bytes | GC Heap 實際佔用與保留虛擬記憶體。 |
| # Induced GC | 手動 GC.Collect() 次數過多視為 Bug。 |
!pe (PrintException) 檢視最後 Managed 例外。~*kb 檢視所有執行緒堆疊,搜尋 mscorwks!RaiseTheException。!threads 最後一欄查看各執行緒最近 Managed 例外。!address -summary 查看 Largest free region。若 < 64MB (32-bit) 或 < 1GB (64-bit) → 虛擬記憶體碎片化。!eeheap -gc 對應 GC 段落位置,判斷碎片是否由 Managed Heap 造成。Available Bytes 接近零。bp mscorwks!WKS::GCHeap::RestartEE "j (dwo(mscorwks!WKS::GCHeap::GcCondemnedGeneration)==2) 'kb';'g'"!dumpheap -stat 依類型統計大小,從尾端最大物件著手分析。!dumpheap -type System.String -min 150 -max 200 檢視內容,常見重複前綴 (如 PendingOrder-) → 適用字串驻留 (String.Intern)。!gcroot <addr> 追蹤根參考,找出為何存活。!gcroot 確認)。!finalizequeue 檢視 Ready for finalization 數量;!threads -special 觀察 Finalizer 執行緒堆疊。臨時解法:GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect();,長期改用 Thread.Join。!dumpheap -type Free -stat 統計 Free 物件總大小 = 碎片量。!gchandles 統計 Pinned Handles,!objsize 找出釘住物件。% Time in GC 計數器:最近一次 GC 耗時 / 上次 GC 結束後經過時間。