HeapAlloc периодически прерывается - PullRequest
1 голос
/ 05 августа 2011

У нас есть DLL (созданная с использованием VC2005), которая выполняет некоторую обработку от имени вызывающего приложения.Эта обработка требует совсем немного памяти.DLL создает эту память через heapAlloc следующим образом:

//Allocate space
myStruct* pStackSpace = (myStruct*)::HeapAlloc(m_hStackHeap, 0, sizeof(myStruct));

...
do some processing here
...

//Free space
::HeapFree(m_hStackHeap, 0, pStackSpace);

Куча распределяется через:

m_hStackHeap = ::HeapCreate(0, sizeof(myStruct)*10, 0);

После создания мы фактически выделяем 20 myStructs, а затем освобождаем их, чтобы убедиться, чтоэто справиться с этим.Итак, мы знаем, что места достаточно.

Проблема в том, что в некоторых случаях HeapAlloc возвращает NULL.Если это произойдет, мы делаем HeapValidate(m_hStackHeap, 0, NULL), который всегда возвращается не равным нулю (то есть все хорошо).Таким образом, мы знаем, что с кучей все в порядке.

Мы также даем понять, что у нас никогда не будет более 10 одновременных распределений одновременно, поэтому должно быть достаточно места, так как первоначальный heapCreate зарезервировал столько.

Следующий вызов HeapAlloc часто завершается успешно.Поведение очень спорадическое.Он будет работать нормально, затем не сможет выделить несколько раз, а затем снова начнет работать нормально.

Есть идеи о том, что происходит?

Ответы [ 3 ]

1 голос
/ 06 августа 2011

Поведение предполагает, что это может быть связано с фрагментацией кучи.У вас может быть достаточно общего пространства кучи, чтобы удовлетворить запрос, но свободных блоков недостаточно.Попробуйте использовать Кучу с низкой фрагментацией.Вы можете сделать это, вызвав HeapSetInformation (), чтобы включить LFH.Обратите внимание, что вы не можете использовать LFH, если вы указали флаг HEAP_NO_SERIALIZE в HeapCreate ().

0 голосов
/ 08 августа 2011

2mb структуры? Рассмотрите возможность использования VirtualAlloc и списка указателей alloc / free.

0 голосов
/ 05 августа 2011

Вместо использования пользовательской кучи вы можете использовать пользовательские подпрограммы ALLOC и FREE, которые сохраняют пул соответствующего размера.

Это делается путем объединения структуры с простым объектом, содержащим указатель NEXT, и одной глобальной переменной, содержащей указатель.

Если вы вышли, выделите новый из глобальной кучи.

Где бы вы уничтожили кучу свободных от всего этого.

...