Pourquoi mes fenêtres fuite d'application console lors de la marche au ralenti? (Et pourquoi le point de pistolet fumant à kernel32.dll ??)
-
18-09-2019 - |
Question
J'ai une application Windows de la console multi-threded qui semble être une fuite de chaque minute mémoire privée d'environ 4 Ko environ.
Dans un effort pour localiser la fuite, j'ai progressivement suspendu chaque fil dans l'application jusqu'à ce que la fuite a cessé, et à ma grande surprise le coupable semble être un fil nommé « Win32Thread ».
Il ne ressemble pas à un fil que j'ai explicitement commencé.
Si j'attache et briser l'application, la trace de la pile ressemble à ceci:
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
Est-ce que quelqu'un a une idée pourquoi cela tout à coup une fuite?
L'application en cours d'exécution comme cela a été pendant environ 40 heures sur un double système de noyau Win2k3 SP2.
Toutes les idées sont greately appréciés.
La solution
Cette trace de la pile semble que ce soit dans le code lié à des minuteries. Je suppose que votre code (ou une bibliothèque que vous utilisez) a commencé une minuterie en utilisant timeSetEvent
ou une fonction similaire. Dans ce cas, la fuite serait probablement dans votre fonction de rappel de la minuterie.
Démarrage d'une minuterie multimédia provoque un fil à créer, et votre rappel sera appelé à partir de ce fil. Une minuterie périodique expliquerait pourquoi il fuit au ralenti.
Autres conseils
Votre demande a tous les (appels de procédure asynchrones) ou des événements VBTT minuterie programmés? callbacks timer le multimédia.
Si votre rappel utilise des appels d'exécution C, ces appels rend fil unique des allocations locales (paresseusement, première fois attribué la fonction est appelée dans un thread) à faire leur travail (_tcstol, sprintf etc). Parce que le fil n'a pas été démarré avec beginthread () ou beginthreadex () cette mémoire ne peut pas être nettoyé lorsque le fil meurt, de sorte que témoigneraient comme une fuite.