Почему у меня консольное приложение Windows при работе на холостом ходу? (А почему пистолет для курения указывает на kernel32.dll ??) - PullRequest
1 голос
/ 05 февраля 2010

У меня есть многопоточное консольное приложение Windows, которое, похоже, каждую минуту пропускает примерно 4 КБ личной памяти.

В попытке локализовать утечку я постепенно приостановил каждый поток в приложении, пока утечка не прекратилась, и, к моему удивлению, виновником кажется поток с именем "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 

Кто-нибудь знает, почему это может внезапно вытечь?

Приложение работало около 40 часов в двухъядерной системе Win2k3 SP2.

Любые идеи приветствуются.

Ответы [ 2 ]

2 голосов
/ 05 февраля 2010

Эта трассировка стека выглядит как в коде, связанном с таймерами. Я предполагаю, что ваш код (или используемая вами библиотека) запустил таймер с помощью timeSetEvent или аналогичной функции. В этом случае утечка, вероятно, будет в вашей функции обратного вызова таймера.

Запуск мультимедийного таймера приводит к созданию потока, и ваш обратный вызов будет вызываться из этого потока. Периодический таймер объяснит, почему он протекает в режиме ожидания.

0 голосов
/ 05 февраля 2010

Есть ли в вашем приложении какие-либо APC (асинхронные вызовы процедур) или запланированные события таймера? Мультимедийный таймер обратного вызова будет.

Если ваш обратный вызов использует вызовы времени выполнения C, эти вызовы делают одноразовые локальные выделения потока (лениво, выделяемые при первом вызове функции в потоке) для выполнения своей работы (_tcstol, sprintf и т. Д.). Поскольку поток не был запущен с beginthread () или beginthreadex (), эта память не может быть очищена, когда поток умирает, так что это может проявиться как утечка.

...