1

呼び出し元のアプリケーションに代わって何らかの処理を行う 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)常にゼロ以外を返す a を実行します (すべてが順調であることを意味します)。したがって、ヒープは問題ないことがわかります。

また、同時に 10 を超える同時割り当てが発生しないことも認めているため、最初の heapCreate で十分に予約されているため、十分なスペースがあるはずです。

HeapAlloc への次の呼び出しは、多くの場合成功します。動作は非常に散発的です。正常に動作し、数回割り当てに失敗してから、再び正常に動作し始めます。

何が起こっているかについてのアイデアはありますか?

4

3 に答える 3

1

この動作は、ヒープの断片化が原因である可能性があることを示唆しています。要求を満たすのに十分な総ヒープ領域があるかもしれませんが、十分な大きさの空きブロックがありません。低断片化ヒープを使用してみてください。これを行うには、HeapSetInformation() を呼び出して LFH を有効にします。HeapCreate() で HEAP_NO_SERIALIZE フラグを指定した場合、LFH を使用できないことに注意してください。

于 2011-08-05T20:18:16.393 に答える
0

カスタムヒープを使用する代わりに、適切なサイズのプールを保持するカスタムALLOCおよびFREEルーチンを使用できます。

これは、構造体をNEXTポインターを含む単純なオブジェクトとポインターを含む1つのグローバル変数と結合することで行われます。

外出中の場合は、グローバルヒープから新しいものを割り当てます。

ヒープを破壊していたはずの場所で、これらすべてを解放します。

于 2011-08-05T18:32:30.137 に答える
0

2MBの構造体?VirtualAlloc と alloc/free ポインター リストの使用を検討してください。

于 2011-08-07T23:05:32.097 に答える