Потоки заблокированы в malloc и свободны, виртуальный размер - PullRequest
1 голос
/ 12 января 2011

Я использую 64-разрядную многопоточную программу на сервере Windows Server 2003 (X64). Это приводит к тому, что некоторые потоки, похоже, навсегда заблокированы в функции malloc или free. Трассировка стека выглядит следующим образом:

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

Кстати, значения параметров, передаваемые новому оператору, здесь не корректны, возможно, из-за оптимизации.

Кроме того, в то же время я обнаружил в проводнике процессов, что виртуальный размер этой программы составляет 10 ГБ, но частные байты и рабочий набор очень малы (<2 ГБ). У нас были некоторые потоки, использующие virtualalloc, но таким образом, чтобы фиксировать память при вызове, и эти потоки не блокируются. </p>

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

Это выглядит странно для меня, кажется, что много виртуального пространства зарезервировано, но не выделено, а malloc / free заблокировано блокировкой. Я предполагаю, есть ли какие-либо повреждения в памяти / объекте, поэтому планируйте включить gflag с pageheap, чтобы устранить это.

Кто-нибудь имел подобный опыт по этому вопросу раньше? Не могли бы вы поделиться со мной, чтобы я мог получить больше подсказок?

Большое спасибо!

Ответы [ 4 ]

2 голосов
/ 12 января 2011

Ваша программа использует PageHeap , который предназначен только для отладки и накладывает тонну накладных расходов памяти. Чтобы увидеть, какие программы активировали PageHeap, сделайте это в командной строке.

% Gflags.exe /p

Чтобы отключить его для вашего процесса, введите это (для MyProg.exe):

% Gflags.exe /p /disable MyProg.exe
1 голос
/ 12 января 2011

Если вашей системе не хватает памяти, это может быть случай, когда операционная система подкачки, это означает, что для одного выделения, в худшем случае ОС может потребоваться найти лучшего кандидата для подкачки, запишите его в диск, освободите память и верните ее. Вы уверены, что он блокируется или может работать очень медленно? Может ли другой поток переставлять память на диск, пока эти два потока ожидают завершения вызова malloc/free?

1 голос
/ 12 января 2011

Мое предпочтительное решение для отладки утечек в собственных приложениях - использовать UMDH для получения последовательных снимков кучи пользовательского режима в процессе, а затем снова запустить UMDH для сравнения снимков.Любые изменения в снимках, вероятно, являются утечкой.

Вы получаете счетчик и размер блоков памяти, распределенных по их выделенному стеку вызовов, поэтому довольно просто увидеть, где находятся самые большие кабели.Утилита работает с операционной системой для анализа выделения кучи Windows для конкретного процесса.

1 голос
/ 12 января 2011

Pageheap.exe обнаруживает большинство ошибок, связанных с кучей - попробуйте Pageheap

Также вам следует обратить внимание на «значения параметров, передаваемые новому ...» - происходит ли это повреждение в режиме отладки?убедитесь, что все оптимизации отключены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...