/* Usage: memalloc.exe >log.txt * * This program prints to standard output a list of the current * allocation of memory blocks (address space), as understood by * the Windows API function VirtualQuery. * * Typical use is to identify ill-behaved dll's that allocate * small amounts of memory in the middle of an application's * address space, thus preventing the allocation of large blocks * of memory even though plenty of memory is available in the aggregate. * * It is a Good Thing if the largest MEM_FREE region reported by * this program is on the order of 1.5 GB. (The maximum process * size allowed by Windows is 2 GB.) * * Known to compile with mingw gcc with -static command line option, * in which case largest MEM_FREE region of slightly over * 2 * 10^9 bytes is observed. * * Rik Littlefield, 7/1/2004. * */ #include #include main (int argc, char* argv[]) { DWORD largestBlock = 0; MEMORY_BASIC_INFORMATION mbi; DWORD dwMemUsed = 0; PVOID pvAddress = 0; CHAR szBuf[512]; memset(&mbi, 0, sizeof(MEMORY_BASIC_INFORMATION)); while(pvAddress < (PVOID)0x80000000 && VirtualQuery(pvAddress, &mbi, sizeof(MEMORY_BASIC_INFORMATION)) == sizeof(MEMORY_BASIC_INFORMATION)) { szBuf[0] = 0; GetModuleFileNameA((HINSTANCE)mbi.AllocationBase, szBuf, 512); printf("Address %x, length %x, state %x",pvAddress,mbi.RegionSize,mbi.State); if (mbi.State == MEM_COMMIT) printf(" MEM_COMMIT"); if (mbi.State == MEM_FREE) printf(" MEM_FREE"); if (mbi.State == MEM_RESERVE) printf(" MEM_RESERVE"); printf(", type %x", mbi.Type); if (mbi.State == MEM_PRIVATE) printf(" MEM_PRIVATE"); if (mbi.State == MEM_IMAGE) printf(" MEM_IMAGE"); if (mbi.State == MEM_MAPPED) printf(" MEM_MAPPED"); printf(" module %s",szBuf); printf("\n"); if (mbi.State == MEM_FREE && mbi.RegionSize > largestBlock) { largestBlock = mbi.RegionSize; } pvAddress = ((BYTE*)mbi.BaseAddress) + mbi.RegionSize; } printf("Largest MEM_FREE region = %x (%d)\n",largestBlock,largestBlock); }