2016-03-15 25 views
1

我在使用WinDbg進行轉儲的高內存壓力.net應用程序上進行事後分析,此過程是Windows服務。有很多句柄的.Net應用程序的高內存使用率

我有一種感覺,這個14GB的進程內存消耗大部分來自中止的線程,因此很多孤兒信號/事件/突變體等。但我無法把所有這些放在一起,並像它們一樣添加它們單個信號量/事件/突變體需要多少內存,以及哪種WinDbg命令對這種情況有幫助?

下面是WinDbg的輸出:

處理

**Type      Count** 

None      90 
Event      5550 
Section      41 
File      1166 
Directory     3 
Mutant      160 
Semaphore     4581 
Key       78 
Token      2 
Thread      553 
IoCompletion    6 
Timer      1 
TpWorkerFactory    3 
ALPC Port     9 
WaitCompletionPacket  33 

解決-summary

--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal 

<unknown>        471  3`86ea2000 ( 14.108 Gb) 92.40% 0.01% 

線程(大量線程的!列出了ThreadAbortException異常)

Lock 
    ID OSID ThreadOBJ   State GC Mode  GC Alloc Context     Domain   Count Apt Exception 

    12 3 33f0 00000017e3c23200 1282b221 Preemptive 0000000000000000:0000000000000000 00000017e3bb3930 1  MTA System.Threading.ThreadAbortException 000000181de5d668 
+0

也可能會有所幫助:https://stackoverflow.com/questions/26142607/how-to-use-windbg-to-track-down-net-out-of-memory-exceptions –

+0

帶*號的是*許多未確定的操作系統資源,您難以理解內存使用率高。一個常見的原因是死鎖的終結器線程,一旦發生內存使用率攀升而沒有界限。在小型轉儲中找到它並查看其調用堆棧。 –

+0

@HansPassant似乎終結線程被阻止從以下輸出,但我沒有看到任何地方在代碼中的終結器存在:0:000>〜[2] k 子SP SPAddAddr調用站點 00000017'fd5bf2c8 00007ffc'd340dd29 ntdll!NtWaitForSingleObject + 0xa 00000017'fd5bf2d0 00007ffc'd340b6f4 ntdll!RtlpWaitOnCriticalSection + 0xe1 –

回答

1

把手及其包裝可能相當小。使用dt -r得到他們的大小的想法:

0:025> dt -r ntdll!_KSEMAPHORE 
    +0x000 Header   : _DISPATCHER_HEADER 
     +0x000 Type    : UChar 
     +0x001 TimerControlFlags : UChar 
     +0x001 Absolute   : Pos 0, 1 Bit 
     +0x001 Coalescable  : Pos 1, 1 Bit 
     +0x001 KeepShifting  : Pos 2, 1 Bit 
     +0x001 EncodedTolerableDelay : Pos 3, 5 Bits 
     +0x001 Abandoned  : UChar 
     +0x001 Signalling  : UChar 
     +0x002 ThreadControlFlags : UChar 
     +0x002 CpuThrottled  : Pos 0, 1 Bit 
     +0x002 CycleProfiling : Pos 1, 1 Bit 
     +0x002 CounterProfiling : Pos 2, 1 Bit 
     +0x002 Reserved   : Pos 3, 5 Bits 
     +0x002 Hand    : UChar 
     +0x002 Size    : UChar 
     +0x003 TimerMiscFlags : UChar 
     +0x003 Index   : Pos 0, 6 Bits 
     +0x003 Inserted   : Pos 6, 1 Bit 
     +0x003 Expired   : Pos 7, 1 Bit 
     +0x003 DebugActive  : UChar 
     +0x003 ActiveDR7  : Pos 0, 1 Bit 
     +0x003 Instrumented  : Pos 1, 1 Bit 
     +0x003 Reserved2  : Pos 2, 4 Bits 
     +0x003 UmsScheduled  : Pos 6, 1 Bit 
     +0x003 UmsPrimary  : Pos 7, 1 Bit 
     +0x003 DpcActive  : UChar 
     +0x000 Lock    : Int4B 
     +0x004 SignalState  : Int4B 
     +0x008 WaitListHead  : _LIST_ENTRY 
     +0x000 Flink   : Ptr64 _LIST_ENTRY 
     +0x008 Blink   : Ptr64 _LIST_ENTRY 
    +0x018 Limit   : Int4B 

使信號燈的尺寸爲0x18 + 4個字節。請注意,如果使用Ptr部件,尺寸可能會增加,例如如果你有一個非常大的等待名單。

我建議在您的情況下使用!dumpheap -stat。這將輸出一個.NET對象列表,按它們的總大小排序。

通常有byte[],object[](或相似)和String吃大多數記憶。

0:025> !dumpheap -mt 000007feef0aea80 
     Address    MT  Size 
[...] 
000007feef0bda88  4915  329862 System.String 
000007feef0be100  1419  382288 System.Object[] 
000007feef05f748  2  786520 System.UInt32[] 
Total 65575 objects 

對於單個對象,您可以使用!objsize <address>。在我的例子中,一個System.Threading.Thread有16 kB。所以即使你有1000個線程,這也只會彌補16MB的內存。 System.Threading.ManualResetEvent的示例在我的應用程序中僅佔80個字節。

0:025> !objsize 0000000011878358 
sizeof(0000000011878358) = 16736 (0x4160) bytes (System.Threading.Thread) 

0:025> !objsize 00000000118af810 
sizeof(00000000118af810) = 80 (0x50) bytes (System.Threading.ManualResetEvent) 
+0

不知道你冒犯了誰,但有人似乎在熱烈歡迎

+0

@LievenKeersmaekers:謝謝。只要我保持在2000以上,就可以在不引起大量審閱工作的情況下編輯,我不再關心聲譽。 –

相關問題