能够处理由任何大小的数据结构所组成的数组,也就是说结构的大小不必正好是页面的大小。因此读者可以轻易将GarbageCollect函数用于自己的应用程序。唯一的要求是结构的第一个成员必须是一个BOOL值,用来表示该结构是否正在使用。
VOID GarbageCollect(PVOID pvBase, DWORD dwNum, DWORD dwStructSize) {
UINT uMaxPages = dwNum * dwStructSize / g_uPageSize;
for (UINT uPage = 0; uPage < uMaxPages; uPage++) {
BOOL bAnyAllocsInThisPage = FALSE;
UINT uIndex = uPage * g_uPageSize / dwStructSize;
UINT uIndexLast = uIndex + g_uPageSize / dwStructSize;
for (; uIndex < uIndexLast; uIndex++) {
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(&g_pSomeData[uIndex], &mbi, sizeof(mbi));
bAnyAllocsInThisPage = ((mbi.State == MEM_COMMIT) &&
* (PBOOL) ((PBYTE) pvBase + dwStructSize * uIndex));
// Stop checking this page, we know we can't decommit it.
if (bAnyAllocsInThisPage) break;
}
if (!bAnyAllocsInThisPage) {
// No allocated structures in this page; decommit it.
VirtualFree(&g_pSomeData[uIndexLast - 1], dwStructSize, MEM_DECOMMIT);
}
}
}