HeapAlloc периодически прерывается

У нас есть 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 ответа

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

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

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

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

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

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

Другие вопросы по тегам