2012-04-05 11 views
4

の調査:は、我々は我々のアプリケーションが遅いメモリリークを持っていると私はすでに漏れの原因をanalyizeしようとする際に、以下の手順を行ってきたメモリリーク

  1. GFLAGSでユーザーモードスタックトレースデータベースを有効にする
  2. 複数のダンプを比較した後、私はサイズ のメモリ・ブロックから0xCていることがわかり ヒープ-stat -h 1250000(1250000が漏れがあり、ヒープのアドレスです) :!次のコマンドを入力してWindbgので
  3. 、時間の経過と共に増加しており、おそらくリークされているメモリです。
  4. 次のコマンドを入力:!ヒープ-flt SC すると、それらの割り当てのUserPtrを与え、最終的に:!これらのアドレスの一部に
  5. を入力してヒープ-p -aアドレスは、常に次の割り当てのコールスタックを示しています:

0:!000>ヒープ-p -a 10576ef8

address 10576ef8 found in 
_HEAP @ 1250000 
    HEAP_ENTRY Size Prev Flags UserPtr UserSize - state 
    10576ed0 000a 0000 [03] 10576ef8 0000c - (busy) 
    mscoreei!CLRRuntimeInfoImpl::`vftable' 
    7c94b244 ntdll!RtlAllocateHeapSlowly+0x00000044 
    7c919c0c ntdll!RtlAllocateHeap+0x00000e64 
    603b14a4 mscoreei!UtilExecutionEngine::ClrHeapAlloc+0x00000014 
    603b14cb mscoreei!ClrHeapAlloc+0x00000023 
    603b14f7 mscoreei!ClrAllocInProcessHeapBootstrap+0x0000002e 
    603b1614 mscoreei!operator new[]+0x0000002b 
    603d402b +0x0000005f 
    603d5142 mscoreei!GetThunkUseState+0x00000025 
    603d6fe8 mscoreei!_CorDllMain+0x00000056 
    79015012 mscoree!ShellShim__CorDllMain+0x000000ad 
    7c90118a ntdll!LdrpCallInitRoutine+0x00000014 
    7c919a6d ntdll!LdrpInitializeThread+0x000000c0 
    7c9198e6 ntdll!_LdrpInitialize+0x00000219 
    7c90e457 ntdll!KiUserApcDispatcher+0x00000007 

ティスレッド初期化コールスタックのように見えますが、これ以上のことを知る必要があります。 指を漏れの正確な原因に置くために行うべき次のステップは何ですか?

答えて

2

まず最初に、新しいオペレータはnew []オペレータなので、対応するdelete[]コールがあり、普通の古いdeleteコールはありませんか?

このコードが疑わしい場合は、テスト・ハーネスをその周りに配置します(ループに入れて100回または1000回実行するなど)。リークと比例しますか?

また、プロセスエクスプローラを使用して、またはGetProcessInformationを使用してプログラムでメモリの増加を測定することもできます。

もう1つの明らかなことは、この関数呼び出しをコメントアウトしたときに何が起こるかを確認することです。メモリリークは消えますか?可能であれば、疑わしいコードを毎回半分(おおまかに)減らすために、可能であればバイナリチョップを行う必要があるかもしれませんが、コードの動作を変更すると、より多くの問題やコードパスの問題が発生する可能性があります。メモリリークや奇妙な動作が発生します。

EDIT 管理対象環境で作業しているときは、次のことを無視してください。あなたはまた、オブジェクトの寿命を管理するために、アレイ構造のためshared_ptrまたはscoped_arrayようSTLまたはいっそboost参照がカウントされ、ポインタを使用して検討すること

+0

言語が指定されていないが、mscoreei!*があると、これは管理された言語なので、削除の必要性、STLの使用、ブーストなどはおそらく適用されません。 – jcopenha

+0

問題は、この呼び出しスタックが私のコードではなくCLRコードを示すので、どこで検索するのかわからないということです。 – galbarm

+0

dllmainがコールのように見えるので、dllをロードしているようですが、mscoreeiとは何ですか?私は何も知らない.netこれはあなたのdllまたはサードパーティーではなく、MS .net dllですか? MS dllがメモリをリークしている可能性は低いので、関数 'bp mscoreei!GetThunkUseState'でブレークポイントを設定できる呼び出しコードによって誤った使い方をする可能性があります。これがコールスタックをチェックし、それが死後のダンプよりも多くの情報を与えるならば、 – EdChum

6

GFlagsを使用するときにスタックが記録されるのは.pdbを使用せずに行われ、しばしば正しくないことがあります。 指定されたヒープ上の特定のサイズにリークをトレースしたので、 を試して、RtlAllocateHeapでライブブレークを設定し、適切なシンボルでwindbgのスタックを調べることができます。私はいくつかの成功で以下を使用しました。ヒープとサイズに合わせて編集する必要があります。

$$ Display stack if heap handle eq 0x00310000 and size is 0x1303 
$$ ==================================================================== 
bp ntdll!RtlAllocateHeap "j ((poi(@esp+4) = 0x00310000) & (poi(@esp+c) = 0x1303))'k';'gc'" 

あなたは違反者のための別のスタックや他のアイデアを得るかもしれません。

関連する問題