web-dev-qa-db-ja.com

windbgの<unclassified>メモリ使用量を分析する方法

これは、x64マシンで実行されている.NET v4Windowsサービスアプリケーションです。何日も着実に実行した後のある時点で、Windowsサービスのメモリ消費量はクラッシュするまで狂ったように急上昇します。 1.2 GBでそれをキャッチし、メモリダンプをキャプチャすることができました。これが私が得るものです

ダンプファイルのwindbgで!address -summaryを実行すると、次の結果が得られます。

!address -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回は1.73 GBとして表示され、もう1回は242MBとして表示されるのはなぜですか。 (これは回答済みです。ありがとうございます)

次に、未分類はマネージコードを意味する可能性があることを理解していますが、!eeheapによるヒープサイズはわずか248 MBで、実際には242に一致しますが、1.73GBには近くありません。ダンプファイルのサイズは1.2GBで、通常よりもはるかに大きくなっています。ここからどこに行って、すべてのメモリを使用しているのかを調べます。マネージドヒープの世界では、すべてが248 MB未満ですが、私は1.2GBを使用しています。

ありがとう

[〜#〜]編集[〜#〜]

!heap -sを実行すると、次のようになります。

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      
-------------------------------------------------------------------------------------
22
Mark

私は最近非常によく似た状況にあり、調査に役立ついくつかのテクニックを見つけました。どれも特効薬ではありませんが、それぞれが問題にもう少し光を当てています。

1)SysInternals(http://technet.Microsoft.com/en-us/sysinternals/dd535533)のvmmap.exeは、ネイティブメモリとマネージメモリの情報を相互に関連付けて、NiceUIに表示するのに適しています。以下の手法を使用して同じ情報を収集できますが、これははるかに簡単で、開始するのに最適な場所です。残念ながら、ダンプファイルでは機能しません。ライブプロセスが必要です。

2)「!address-summary」出力は、より詳細な「!address」出力のロールアップです。詳細な出力をExcelにドロップして、いくつかのピボットを実行すると便利だと思いました。この手法を使用して、「」としてリストされた多数のバイトが実際にはMEM_IMAGEページであり、DLLがロードされたときにロードされたが、データが変更されたときにコピーされたデータページのコピーである可能性が高いことを発見しました。また、広い領域にフィルタリングして、特定のアドレスにドリルインすることもできます。つまようじでメモリダンプをつつき、たくさんの祈りをするのは苦痛ですが、明らかになる可能性があります。

3)最後に、上記のvmmap.exeテクニックの貧乏人バージョンを実行しました。ダンプファイルをロードし、ログを開いて、!address、!eeheap、!heap、および!threadsを実行しました。また、〜* kにリストされているスレッド環境ブロックを!tebでターゲットにしました。ログファイルを閉じて、お気に入りのエディターにロードしました。次に、分類されていないブロックを見つけて検索し、より詳細なコマンドの1つからの出力にポップアップが表示されるかどうかを確認しました。ネイティブヒープとマネージヒープを非常に迅速に関連付けて、疑わしい未分類の領域からそれらを取り除くことができます。

これらはすべて手動です。上記のテクニック3で生成したものと同様の出力を取得し、vmmap.exeの表示に適したmmpファイルを出力するスクリプトを作成したいと思います。いつか。

最後の注意:vmmap.exeの出力と!addressの出力を関連付け、vmmapのカップルがさまざまなソースから識別するこれらのタイプの領域(!heapおよび!eeheapが使用するものと同様)に注目しましたが、!addressは認識していませんでした約。つまり、これらはvmmap.exeがラベル付けしたものですが、!addressはラベル付けしませんでした。

.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

まだ説明されていない「プライベート」バイトがたくさんありましたが、これらを取り除くことができれば、問題を絞り込むことができます。

これが調査方法に関するいくつかのアイデアを提供することを願っています。私は同じ船に乗っているので、あなたも見つけていただければ幸いです。ありがとう!

17
Vince

「使用状況の概要」は、未分類の3696の領域があり、合計で17.33Gbであることを示しています。

「最大の領域」は、未分類の領域の最大が242Mbであることを示しています。未分類の残り(3695領域)を合わせると、最大17.33Gbの差が生じます。

!heap –sを実行し、Virt colを合計して、ネイティブヒープのサイズを確認してください。これらも、管理されていないバケットに分類されると思います。 (NB以前のバージョンでは、!address -summaryから明示的なネイティブヒープが表示されます)

2
Kjell Gunnar

Windbg(http://msdn.Microsoft.com/en-us/library/bb190764.aspx)でEEHeapコマンドとGCHandlesコマンドを使用して、リークしている可能性のあるものを見つけることができるかどうかを確認することをお勧めします。そのように間違っています。

残念ながら、これらのタイプの問題の診断はほとんどの場合非常に時間がかかり、最も単純なケース以外では誰かがダンプを完全に分析する必要があるため、探している正確なヘルプを得ることができない可能性があります。基本的に、誰かがスタックオーバーフローの直接的な答えにあなたを向けることができる可能性は低いです。ほとんどの人はあなたに役立つかもしれないコマンドを指すことができるでしょう。何が起こっているのかについてより多くの情報を見つけるために、あなたは多くの掘り下げをしなければならないでしょう。

1
Zipper

「未分類」にとってより意味のあるものを表示できるように見えるWindows6.11.1.404用のDebuggingToolsのコピーを保持しています。

そのバージョンでは、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)では、これを同じダンプから取得します。私が注意する2つのこと:

データは、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)
1
Pete

私は最近、アプリが終了する前に70 GBを使用していたという顧客の問題の診断に時間を費やしました(おそらくIISアプリプールのリサイクル制限に達したためですが、まだ確認されていません)。彼らは35GBのメモリを送ってくれました。ダンプ。私の最近の経験に基づいて、あなたが提供したものについて私が行うことができるいくつかの観察があります:

!heap -s出力では、1.247GBのうち284MBが[コミット]列に表示されます。 DebugDiagでこのダンプを開くと、ヒープ0x60000に1GBのコミット済みメモリがあることがわかります。報告された11セグメントのコミットサイズを合計すると、合計が約102 MBであり、1GBではないことがわかります。とても腹立たしい。

「欠落している」メモリは欠落していません。これは、実際には!heap -sの出力で「Virtualblock:」行として示唆されています。残念ながら、!heap -sは、終了アドレスを正しく表示しないため、サイズを0として報告します。次のコマンドの出力を確認してください。

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

適切な終了アドレス、したがって正確な「リージョンサイズ」が報告されます。さらに良いことに、それは領域サイズの簡潔なバージョンを提供します。これらの3つのリージョンのサイズを102MBに追加すると、1GBにかなり近くなるはずです。

それで、それらには何が含まれていますか?さて、あなたはdqを使って見ることができます。洞窟探検をすることで、なぜ彼らが割り当てられたのかについてのヒントを見つけるかもしれません。おそらく、マネージコードはネイティブサイドを持つサードパーティコードを呼び出します。

!heap 6fff0000 -x -vを使用すると、ヒープへの参照を見つけることができる場合があります。参照がある場合は、!addressを再度使用することで、参照が存在するメモリ領域を確認できます。私の顧客の問題で、「使用法:スタック」のある地域に住んでいる参照を見つけました。 「詳細情報:」ヒントは、スタックのスレッドを参照していました。このスレッドの上部には、大きなbasic_stringの追加/コピー呼び出しがありました。

0
Jeffrey LeCours