2011-01-12 5 views
1

Ich bin ein 64-Bit-Multithread-Programm auf dem Windows Server 2003-Server (X64) laufen, lief es in einem Fall, dass einige der Threads in blockiert scheinen das malloc oder die freie Funktion für immer. Der Stack-Trace ist wie folgt:Threads sind in Malloc und freie, virtuelle Größe blockiert

ntdll.dll!NtWaitForSingleObject() + 0xa bytes 
ntdll.dll!RtlpWaitOnCriticalSection() - 0x1aa bytes  
ntdll.dll!RtlEnterCriticalSection() + 0xb040 bytes 
ntdll.dll!RtlpDebugPageHeapAllocate() + 0x2f6 bytes  
ntdll.dll!RtlDebugAllocateHeap() + 0x40 bytes 
ntdll.dll!RtlAllocateHeapSlowly() + 0x5e898 bytes 
ntdll.dll!RtlAllocateHeap() - 0x1711a bytes  
MyProg.exe!malloc(unsigned __int64 size=0) Line 168 C 
MyProg.exe!operator new(unsigned __int64 size=1) Line 59 + 0x5 bytes C++ 


ntdll.dll!NtWaitForSingleObject() 
ntdll.dll!RtlpWaitOnCriticalSection() 
ntdll.dll!RtlEnterCriticalSection()  
ntdll.dll!RtlpDebugPageHeapFree() 
ntdll.dll!RtlDebugFreeHeap()  
ntdll.dll!RtlFreeHeapSlowly() 
ntdll.dll!RtlFreeHeap()  
MyProg.exe!free(void * pBlock=0x000000007e8e4fe0) C 

BTW, ist die param Werte an den neuen Betreiber übergeben nicht richtig hier vielleicht durch Optimierung.

Auch zur gleichen Zeit, fand ich im Prozess Explorer, ist die virtuelle Größe dieses Programms 10 GB, aber die privaten Bytes und Arbeitssatz ist sehr klein (< 2GB). Wir hatten einige Threads mit virtualalloc, aber auf eine Weise, die den Speicher im Aufruf festschreibt, und diese Threads sind nicht blockiert.

m_pBuf = VirtualAlloc(NULL, m_size, MEM_COMMIT, PAGE_READWRITE); 
...... 
VirtualFree(m_pBuf, 0, MEM_RELEASE); 

Das sieht mir seltsam, scheint eine Menge virtuellen Raum reserviert, aber nicht verpflichtet und malloc/free durch Sperre blockiert. Ich vermute, dass es in dem Speicher/Objekt irgendwelche Beschädigungen gibt, also plane gflag mit pageheap um dies zu beheben.

Hat jemand ähnliche Erfahrung auf diesem zuvor? Könntest du mit mir teilen, damit ich weitere Hinweise bekomme?

Vielen Dank!

+0

ein weiteres Update, das O ein Popup zu tun hatte „aus virtuellem Speicher“, als dies geschah zu sagen.Ich schätze, genau wie EmeryBerger es gesagt hat, weil ich aus Versehen den Seitenzugriff aktiviert habe, bevor ich mein Programm starte. Vielen Dank für die tolle Information, sehr geschätzt! –

Antwort

1

Pageheap.exe erkennt die meisten Heap-bezogene Fehler - versuchen Pageheap

Auch sollten Sie schauen, um „die param Werte auf die neue vergangen ...“ - ist diese beschädigt werden in den Debug-Modus? Stellen Sie sicher, dass alle Optimierungen deaktiviert sind.

1

Wenn auf Ihrem System nicht genügend Arbeitsspeicher verfügbar ist, kann es vorkommen, dass das Betriebssystem ausgetauscht wird. Das bedeutet, dass das Betriebssystem im schlimmsten Fall den besten Kandidaten für das Swapping finden muss, um es zu schreiben auf die Festplatte, befreie den Speicher und gib ihn zurück. Sind Sie sicher, dass es gesperrt ist oder läuft es nur sehr langsam? Kann ein anderer Thread den Speicher auf den Datenträger wechseln, während diese beiden Threads darauf warten, dass der Aufruf an malloc/free abgeschlossen wird?

+0

Danke für die tolle Information. Das malloc/free kam in meinem Fall nie zurück. Ich denke, das könnte daran liegen, dass ich pageheap aus Versehen aktiviert habe, bevor ich dieses Programm ausführte. Der verursachte Overhead könnte also so groß sein, dass malloc/free nie zurückgegeben wird. –

1

Meine bevorzugte Lösung zum Debuggen von Lecks in nativen Anwendungen in UMDH zu verwenden, um aufeinanderfolgende Snapshots der Benutzermodus Heap (s) im Prozess zu erhalten und dann wieder UMDH zu Diff die Snapshots. Jedes Änderungsmuster in den Snapshots ist wahrscheinlich ein Leck.

Sie erhalten eine Anzahl und Größe von Speicherblöcken, die durch ihren allozierenden Callstack bucket sind, so dass es ziemlich einfach ist zu sehen, wo die größten Schweine sind.

Der Benutzer-Modus-Dump Heap (UMDH) Dienstprogramm zu mit dem Betriebssystem arbeitet für einen spezifischen Prozess Windows-Heapzuweisungen analysieren.

2

Ihr Programm verwendet PageHeap, das nur zum Debuggen vorgesehen ist und eine Menge Speicheraufwand verursacht. Um zu sehen, welche Programme PageHeap aktiviert haben, tun Sie dies in einer Befehlszeile.

% Gflags.exe /p 

es für Ihren Prozess zu deaktivieren, geben Sie diese (für myprog.exe):

% Gflags.exe /p /disable MyProg.exe 
+0

Ja, ich denke das ist genau mein Problem. Ich habe versucht, den Seitenzugriff zur Fehlerbehebung zu aktivieren, habe dann aber festgestellt, dass sie bereits aktiviert ist. Also vielen Dank! Übrigens, hast du das durch die von mir geposteten Callstacks herausgefunden? Auch habe ich nicht bemerkt, dass diese Art von Seiteneffekten möglicherweise passieren wird, wenn die Seite angeschaltet wird. –

+0

Ja, es ist auf Ihren Aufrufstacks (RtlpDebugPageHeapAllocate), und das Symptom des massiven reservierten virtuellen Adressraums hat es ziemlich bestätigt :). – EmeryBerger

Verwandte Themen