2012-01-26 48 views
21

這是在x64機器上運行的.NET v4 Windows服務應用程序。在穩定運行幾天之後的某個時刻,Windows服務內存的消耗像瘋了似的瘋狂直到崩潰。我能夠以1.2 GB的速度捕獲它並捕獲內存轉儲。以下是我得到如何分析windbg中的<未分類>內存使用情況

如果我跑了!在WinDbg中解決-summary在我的轉儲文件,我得到後續結果

!解決-summary

--- Usage Summary ------ RgnCount ------- Total Size -------- %ofBusy %ofTotal 
Free      821  7ff`7e834000 ( 7.998 Tb)   99.98% 
<unclassified>   3696  0`6eece000 ( 1.733 Gb) 85.67% 0.02% 
Image     1851  0`0ea6f000 (234.434 Mb) 11.32% 0.00% 
Stack     1881  0`03968000 ( 57.406 Mb) 2.77% 0.00% 
TEB      628  0`004e8000 ( 4.906 Mb) 0.24% 0.00% 
NlsTables    1   0`00023000 (140.000 kb) 0.01% 0.00% 
ActivationContextData 3   0`00006000 ( 24.000 kb) 0.00% 0.00% 
CsrSharedMemory   1   0`00005000 ( 20.000 kb) 0.00% 0.00% 
PEB      1   0`00001000 ( 4.000 kb) 0.00% 0.00% 
- 
- 
- 
--- Type Summary (for busy) -- RgnCount ----- Total Size ----- %ofBusy %ofTotal 
MEM_PRIVATE      5837 0`7115a000 ( 1.767 Gb) 87.34% 0.02% 
MEM_IMAGE       2185 0`0f131000 (241.191 Mb) 11.64% 0.00% 
MEM_MAPPED       40 0`01531000 (21.191 Mb) 1.02% 0.00% 
- 
- 
--- State Summary ------------ RgnCount ------ Total Size ---- %ofBusy %ofTotal 
MEM_FREE       821 7ff`7e834000 ( 7.998 Tb)  99.98% 
MEM_COMMIT       6127 0`4fd5e000 ( 1.247 Gb) 61.66% 0.02% 
MEM_RESERVE      1935 0`31a5e000 (794.367 Mb) 38.34% 0.01% 
- 
- 
--Protect Summary(for commit)- RgnCount ------ Total Size --- %ofBusy %ofTotal 
PAGE_READWRITE      3412 0`3e862000 (1000.383 Mb) 48.29% 0.01% 
PAGE_EXECUTE_READ     220 0`0b12f000 (177.184 Mb) 8.55% 0.00% 
PAGE_READONLY      646 0`02fd0000 ( 47.813 Mb) 2.31% 0.00% 
PAGE_WRITECOPY      410 0`01781000 ( 23.504 Mb) 1.13% 0.00% 
PAGE_READWRITE|PAGE_GUARD   1224 0`012f2000 ( 18.945 Mb) 0.91% 0.00% 
PAGE_EXECUTE_READWRITE    144 0`007b9000 ( 7.723 Mb) 0.37% 0.00% 
PAGE_EXECUTE_WRITECOPY    70 0`001cd000 ( 1.801 Mb) 0.09% 0.00% 
PAGE_EXECUTE       1 0`00004000 ( 16.000 kb) 0.00% 0.00% 
- 
- 
--- Largest Region by Usage ----Base Address -------- Region Size ---------- 
Free       0`8fff0000  7fe`59050000 ( 7.994 Tb) 
<unclassified>     0`80d92000  0`0f25e000 (242.367 Mb) 
Image       fe`f6255000  0`0125a000 ( 18.352 Mb) 
Stack       0`014d0000  0`000fc000 (1008.000 kb) 
TEB        0`7ffde000  0`00002000 ( 8.000 kb) 
NlsTables      7ff`fffb0000  0`00023000 (140.000 kb) 
ActivationContextData   0`00030000  0`00004000 ( 16.000 kb) 
CsrSharedMemory     0`7efe0000  0`00005000 ( 20.000 kb) 
PEB        7ff`fffdd000  0`00001000 ( 4.000 kb) 

首先,爲什麼會非保密現身一次爲1.73 GB,另一次爲242 MB。第二,我明白,未分類可以意味着託管代碼,但是我的堆大小根據!eeheap只有248 MB,它實際上匹配242,但不是接近於1.73GB。轉儲文件大小爲1.2 GB,比正常情況高很多。我在哪裏可以從這裏瞭解什麼是使用所有的記憶。託管堆世界中的任何內容都在248 MB以下,但我使用的是1.2 GB。

感謝

編輯

如果我這樣做!堆-si得到以下

LFH Key     : 0x000000171fab7f20 
Termination on corruption : ENABLED 
      Heap  Flags Reserv Commit Virt Free List UCR Virt Lock Fast 
          (k)  (k) (k)  (k) length  blocks cont. heap 
------------------------------------------------------------------------------------- 
Virtual block: 00000000017e0000 - 00000000017e0000 (size 0000000000000000) 
Virtual block: 0000000045bd0000 - 0000000045bd0000 (size 0000000000000000) 
Virtual block: 000000006fff0000 - 000000006fff0000 (size 0000000000000000) 
0000000000060000 00000002 113024 102028 113024 27343 1542 11 3 1c LFH 
    External fragmentation 26 % (1542 free blocks) 
0000000000010000 00008000  64  4  64  1  1  1 0 0  
0000000000480000 00001002 3136 1380 3136  20  8  3 0 0 LFH 
0000000000640000 00041002  512  8 512  3  1  1 0 0  
0000000000800000 00001002 3136 1412 3136  15  7  3 0 0 LFH 
00000000009d0000 00001002 3136 1380 3136  19  7  3 0 0 LFH 
00000000008a0000 00041002  512  16 512  3  1  1 0 0  
0000000000630000 00001002 7232 3628 7232  18 53  4 0 0 LFH 
0000000000da0000 00041002 1536 856 1536  1  1  2 0 0 LFH 
0000000000ef0000 00041002 1536 944 1536  4 12  2 0 0 LFH 
00000000034b0000 00001002 1536 1452 1536  6 17  2 0 0 LFH 
00000000019c0000 00001002 3136 1396 3136  16  6  3 0 0 LFH 
0000000003be0000 00001002 1536 1072 1536  5  7  2 0 3 LFH 
0000000003dc0000 00011002  512 220 512 100 60  1 0 2  
0000000002520000 00001002  512  8 512  3  2  1 0 0  
0000000003b60000 00001002 339712 168996 339712 151494 976 116 0 18 LFH 
    External fragmentation 89 % (976 free blocks) 
    Virtual address fragmentation 50 % (116 uncommited ranges) 
0000000003f20000 00001002  64  8  64  3  1  1 0  0  
0000000003d90000 00001002  64  8  64  3  1  1 0  0  
0000000003ee0000 00001002  64  16  64  11  1  1 0  0  
------------------------------------------------------------------------------------- 
+0

使用SOS dll並查看堆的方式。由於這是一個.net程序,.NET框架所做的堆分配不會顯示在非託管堆中。 – Zipper

+0

根據!eeheap(sos.dll),我的堆大小僅爲248 MB。所以我不確定這是1.2 GB進程大小的原因,也不是1.7GB的原因,除非我錯過了什麼 – Mark

+0

你的服務是做什麼的?您的服務是否包含非託管或C++/CLI代碼?它看起來像一個非託管內存泄漏。 GDI,用戶對象,句柄計數說什麼?哪些調用堆棧被你的線程卡住? 〜* e!ClrStack和〜* e!DumpStack和〜* ekv是你的朋友,看看你的線程在做什麼。一個線程正在分配內容? –

回答

2

「使用摘要」告訴你的非保密3696個區域產生總共17.33 Gb

「Largest Region」表示最大的未分類區域是242 Mb。 未分類(3695個地區)的其餘部分一起使差異達到17.33 Gb。

嘗試做一堆!-s並總結Virt col以查看本機堆的大小,我認爲這些也落入了非託管存儲區。 (NB早期版本顯示來自!address -summary的本地堆棧)

+0

感謝您使用摘要vs最大區域的解釋。我已經做了!堆-s和總結了美國山口,我得到359.12 MB。這是說什麼嗎?我已經添加了!堆的結果-s – Mark

+0

沒有抱歉,因爲這是一個64位轉儲,我沒有實際經驗。順便說一下,哪個版本的.NET是從轉儲?這可能是其他可能知道更多的興趣 –

+0

我已經將這些信息添加到他的問題描述中。它是.NET 4.0 – Mark

1

最好的辦法是在windbg中使用EEHeap和GCHandles命令(http://msdn.microsoft.com/en-us/ library/bb190764.aspx),並嘗試查看是否可以找到可能會漏出/錯誤的方式。

不幸的是,由於診斷這些類型的問題幾乎總是非常耗時且在最簡單的情況下需要有人做一個完整的事實,您可能無法獲得您正在尋找的確切幫助分析轉儲。基本上,不太可能有人能夠指引你直接回答堆棧溢出問題。大多數人可以指出你可能有用的命令。你將不得不做大量的挖掘工作,才能找到更多關於正在發生的事情的信息。

+0

指出正確的方向就足夠了。就像我說的EEHeap似乎只描述了整個事情的248 MB,所以我不確定答案是否可以在那裏。我會看看GCHandles – Mark

16

我最近有一個非常相似的情況,並發現一些在調查中有用的技術。沒有什麼是一顆銀彈,但每個問題都有一點亮點。

1)來自SysInternals(http://technet.microsoft.com/en-us/sysinternals/dd535533)的vmmap.exe在關聯本機和託管內存上的信息方面做得非常好,並在良好的用戶界面中呈現它。使用下面的技術可以收集相同的信息,但這樣更容易,也是一個很好的開始。可悲的是,它不適用於轉儲文件,您需要一個實時進程。

2)「!address -summary」輸出是更詳細的「!address」輸出的彙總。我發現將詳細輸出放入Excel並運行一些支點很有用。使用這種技術,我發現被列爲「」的大量字節實際上是MEM_IMAGE頁面,可能是加載DLL時加載的數據頁的副本,但在數據更改時複製。我也可以過濾到大的區域並鑽入特定的地址。用牙籤和大量祈禱在記憶中傾倒是痛苦的,但可以揭示。

3)最後,我做了一個窮人的版本的vmmap.exe技術上面。我加載了轉儲文件,打開了一個日誌,並運行!address,!eeheap,!heap和!threads。我還將〜* k中列出的線程環境塊與!teb對準。我關閉了日誌文件並將其加載到我最喜歡的編輯器中。然後,我可以找到一個未分類的程序塊,並搜索它是否從其中一個更詳細的命令的輸出中彈出。您可以快速關聯本機堆棧和託管堆,以清除可疑未分類區域中的那些堆棧。

這些都是太手動。我很想編寫一個腳本,它的輸出與我在上面的技巧3中生成的輸出類似,並輸出適合查看vmmap.exe的mmp文件。有一天。

最後一個注意事項:我在vmmap.exe的輸出和!地址輸出之間做了一個關聯,並注意到vmmap耦合了來自各種源(類似於堆!和!eeheap使用的地方)的這些類型,但是!地址不知道。也就是說,這些事情vmmap.exe標記,但報告沒有!

.data 
.pdata 
.rdata 
.text 
64-bit thread stack 
Domain 1 
Domain 1 High Frequency Heap 
Domain 1 JIT Code Heap 
Domain 1 Low Frequency Heap 
Domain 1 Virtual Call Stub 
Domain 1 Virtual Call Stub Lookup Heap 
Domain 1 Virtual Call Stub Resolve Heap 
GC 
Large Object Heap 
Native heaps 
Thread Environment Blocks 

仍然有大量的「私有」字節下落不明,但同樣,我能如果以縮小問題我可以除掉這些。

希望這給你一些關於如何調查的想法。我在同一條船上,所以我會很感激你找到的。謝謝!

+0

「我很想寫一個腳本......查看vmmap」:你有機會這樣做嗎? –

1

我一直在調試工具的Windows 6.11.1.404副本這似乎是能夠顯示的東西「未分類」

與該版本更有意義,我看到TEB地址的列表,然後這個:

0:000> !address -summary 
--------- PEB fffde000 not found ---- 
TEB fffdd000 in range fffdb000 fffde000 
TEB fffda000 in range fffd8000 fffdb000 
...snip... 
TEB fe01c000 in range fe01a000 fe01d000 
ProcessParametrs 002c15e0 in range 002c0000 003c0000 
Environment 002c0810 in range 002c0000 003c0000 
-------------------- Usage SUMMARY -------------------------- 
    TotSize (  KB) Pct(Tots) Pct(Busy) Usage 
    41f08000 (1080352) : 25.76% 34.88% : RegionUsageIsVAD 
    42ecf000 (1096508) : 26.14% 00.00% : RegionUsageFree 
    5c21000 ( 94340) : 02.25% 03.05% : RegionUsageImage 
    c900000 ( 205824) : 04.91% 06.64% : RegionUsageStack 
      0 (  0) : 00.00% 00.00% : RegionUsageTeb 
    68cf8000 (1717216) : 40.94% 55.43% : RegionUsageHeap 
      0 (  0) : 00.00% 00.00% : RegionUsagePageHeap 
      0 (  0) : 00.00% 00.00% : RegionUsagePeb 
      0 (  0) : 00.00% 00.00% : RegionUsageProcessParametrs 
      0 (  0) : 00.00% 00.00% : RegionUsageEnvironmentBlock 
     Tot: ffff0000 (4194240 KB) Busy: bd121000 (3097732 KB) 

-------------------- Type SUMMARY -------------------------- 
    TotSize (  KB) Pct(Tots) Usage 
    42ecf000 (1096508) : 26.14% : <free> 
    5e6e000 ( 96696) : 02.31% : MEM_IMAGE 
    28ed000 ( 41908) : 01.00% : MEM_MAPPED 
    b49c6000 (2959128) : 70.55% : MEM_PRIVATE 

-------------------- State SUMMARY -------------------------- 
    TotSize (  KB) Pct(Tots) Usage 
    9b4d1000 (2544452) : 60.67% : MEM_COMMIT 
    42ecf000 (1096508) : 26.14% : MEM_FREE 
    21c50000 ( 553280) : 13.19% : MEM_RESERVE 

Largest free region: Base bc480000 - Size 38e10000 (931904 KB) 

與我的「當前」版本(6.12.2.633),我從同一個轉儲得到這個。我注意到兩件事:

數據似乎是HeapAlloc/RegionUsageHeap和VirtualAlloc/RegionUsageIsVAD的總和)。

可愛的EFAIL錯誤,毫無疑問,部分原因是缺少數據!

我不知道如何來幫你託管代碼,但我認爲它實際上回答了原來的問題;-)

0:000> !address -summary 


Failed to map Heaps (error 80004005) 

--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal 
<unclassified>       7171   aab21000 ( 2.667 Gb) 90.28% 66.68% 
Free         637   42ecf000 ( 1.046 Gb)   26.14% 
Stack         603   c900000 (201.000 Mb) 6.64% 4.91% 
Image         636   5c21000 ( 92.129 Mb) 3.05% 2.25% 
TEB          201    c9000 (804.000 kb) 0.03% 0.02% 
ActivationContextData     14    11000 ( 68.000 kb) 0.00% 0.00% 
CsrSharedMemory       1    5000 ( 20.000 kb) 0.00% 0.00% 

--- Type Summary (for busy) ------ RgnCount ----------- Total Size -------- %ofBusy %ofTotal 
MEM_PRIVATE       7921   b49c6000 ( 2.822 Gb) 95.53% 70.55% 
MEM_IMAGE        665   5e6e000 ( 94.430 Mb) 3.12% 2.31% 
MEM_MAPPED        40   28ed000 ( 40.926 Mb) 1.35% 1.00% 

--- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal 
MEM_COMMIT        5734   9b4d1000 ( 2.427 Gb) 82.14% 60.67% 
MEM_FREE        637   42ecf000 ( 1.046 Gb)   26.14% 
MEM_RESERVE       2892   21c50000 (540.313 Mb) 17.86% 13.19% 

--- Protect Summary (for commit) - RgnCount ----------- Total Size -------- %ofBusy %ofTotal 
PAGE_READWRITE       4805   942bd000 ( 2.315 Gb) 78.37% 57.88% 
PAGE_READONLY       215   3cbb000 ( 60.730 Mb) 2.01% 1.48% 
PAGE_EXECUTE_READ      78   2477000 ( 36.465 Mb) 1.21% 0.89% 
PAGE_WRITECOPY       74   75b000 ( 7.355 Mb) 0.24% 0.18% 
PAGE_READWRITE|PAGE_GUARD    402   3d6000 ( 3.836 Mb) 0.13% 0.09% 
PAGE_EXECUTE_READWRITE     80   3b0000 ( 3.688 Mb) 0.12% 0.09% 
PAGE_EXECUTE_WRITECOPY     80   201000 ( 2.004 Mb) 0.07% 0.05% 

--- Largest Region by Usage ----------- Base Address -------- Region Size ---------- 
<unclassified>        786000   17d9000 ( 23.848 Mb) 
Free          bc480000   38e10000 (910.063 Mb) 
Stack          6f90000    fd000 (1012.000 kb) 
Image          3c3c000   ebe000 ( 14.742 Mb) 
TEB           fdf8f000    1000 ( 4.000 kb) 
ActivationContextData       190000    4000 ( 16.000 kb) 
CsrSharedMemory        7efe0000    5000 ( 20.000 kb) 
0

最近我花了一些時間來診斷客戶的問題,他們的應用程序在終止前使用了70GB(可能是由於遇到IIS應用程序池回收限制,但仍未確認)。他們給我發送了一個35 GB的內存轉儲。根據我最近的經驗,以下是我可以對您提供的內容進行的一些觀察:

在!堆-s輸出中,「提交」列中顯示了1.247 GB的284 MB。如果您要在DebugDiag中打開此轉儲,它會告訴您堆0x60000具有1 GB的提交內存。您將合計報告的11個細分的提交大小,並發現它們僅添加了大約102 MB而不是1GB。很煩人。

「丟失」的內存不會丟失。它實際上在!heap -s輸出中暗示爲「虛擬塊:」行。 !遺憾的是,堆-s吸並沒有正確顯示的結束地址,因此報告的大小爲0檢查下列命令的輸出:

!address 17e0000 
!address 45bd0000 
!address 6fff0000 

它會報告正確的結束地址,因此一個準確的「區域大小「。更好的是,它提供了一個簡潔版本的區域大小。如果將這3個區域的大小添加到102 MB,則應該接近1 GB。

那麼它們是什麼?那麼,你可以看看使用dq。通過深入探討,你可能會發現他們被分配的原因。也許你的託管代碼調用了一些本地方的第三方代碼。

您可能會使用!heap 6fff0000 -x -v找到堆的引用。如果有參考文獻,您可以通過再次使用!地址查看他們居住的存儲區域。在我的客戶問題中,我找到了一個生活在「Usage:Stack」區域的參考。一個「更多信息:」提示引用了堆棧的線程,它碰巧在頂部有一些大的basic_string追加/複製調用。

相關問題