我们有一个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的调用通常会成功。这种行为是非常零星的。它会工作正常,然后无法分配几次然后再次开始正常工作。
有关正在发生的事情的任何想法?
答案 0 :(得分:1)
行为表明它可能是由于堆碎片造成的。您可能有足够的总堆空间来满足请求,但没有足够大的空闲块。尝试使用低碎片堆。您可以通过调用HeapSetInformation()来启用LFH。请注意,如果在HeapCreate()中指定了HEAP_NO_SERIALIZE标志,则无法使用LFH。
答案 1 :(得分:0)
您可以使用自定义ALLOC和FREE例程来保留适当大小的池,而不是使用自定义堆。
这是通过将struct与一个包含NEXT指针的简单对象和一个包含指针的全局变量结合起来完成的。
如果你要从全局堆中分配一个新的。
你将破坏所有这些堆的地方。
答案 2 :(得分:0)
2mb结构?考虑使用VirtualAlloc和alloc / free指针列表。