1

毎分約 4kb のプライベート メモリをリークしているように見える Windows マルチスレッド コンソール アプリケーションがあります。

リークを特定するために、リークが止まるまでアプリケーションの各スレッドを徐々に中断しました。驚いたことに、原因は「Win32Thread」という名前のスレッドのようです。

私が明示的に開始したスレッドのようには見えません。

アプリケーションをアタッチして中断すると、スタック トレースは次のようになります。

    ntdll.dll!_KiFastSystemCallRet@0()  
    ntdll.dll!_NtCancelTimer@8()  + 0xc bytes   
    ntdll.dll!_RtlpResetTimer@12()  + 0x15 bytes    
>   ntdll.dll!_RtlpServiceTimer@12()  + 0xfd bytes  
    ntdll.dll!_KiUserApcDispatcher@16()  + 0x25 bytes   
    kernel32.dll!_BaseThreadStart@8()  + 0x34 bytes 

なぜこれが突然リークするのか、誰にも分かりますか?

アプリケーションは、Win2k3 SP2 デュアル コア システムで約 40 時間実行されています。

どんなアイデアでも大歓迎です。

4

2 に答える 2

2

そのスタック トレースは、タイマーに関連するコードにあるようです。timeSetEventあなたのコード(またはあなたが使用するライブラリ)は、または同様の関数を使用してタイマーを開始したと思います。その場合、リークはおそらくタイマー コールバック関数にあるでしょう。

マルチメディア タイマーを開始すると、スレッドが作成され、そのスレッドからコールバックが呼び出されます。定期的なタイマーは、アイドリング中にリークする理由を説明します。

于 2010-02-05T12:33:51.127 に答える
0

アプリケーションに APC (非同期プロシージャ コール) またはスケジュールされたタイマー イベントがありますか? マルチメディア タイマーのコールバックがそうです。

コールバックが C ランタイム呼び出しを使用する場合、これらの呼び出しは、その作業 (_tcstol、sprintf など) を実行するために、1 回限りのスレッド ローカル割り当て (遅延、関数がスレッドで最初に呼び出されたときに割り当てられる) を行います。スレッドが beginthread() または beginthreadex() で開始されていないため、スレッドが停止したときにこのメモリをクリーンアップできず、リークとして明らかになります。

于 2010-02-05T16:57:13.113 に答える