xp下用户措施空间分派(7):Heap
副标题#e#
我们都知道在措施里可以利用malloc在堆上分派内存,显然windows应该为这个Heap分派一块空间的 ,我们在主措施里用malloc分派一小块内存,看看指针指向那边:
char* p = (char*)malloc (10);
获得一个指针:0x00b267b0
在内存块内里找,很容易就发明白方针:
从这里可以发明malloc回收的算法并不会在一开始就分派一块很大的内存,假如我们接着用:
p = (char*)malloc(0x10000);
分派一块64K的内存,这时可以发明又多了一块内存:
而这块内存在第一次分派时是空闲的。
由此可以揣摩,malloc可以分派获得的最大内存块应该取 决于最大的空闲块。写段代码测试一下:
void block_test()
{
SYSTEM_INFO info;
MEMORY_BASIC_INFORMATION mi;
HANDLE hProcess;
DWORD dwAddr;
MEMORY_BASIC_INFORMATION miBlock[1000];
int nCount = 0, nMaxSize = 0;
char* p = NULL;
hProcess = GetCurrentProcess();
GetSystemInfo(&info);
dwAddr = (DWORD)info.lpMinimumApplicationAddress;
do
{
VirtualQueryEx(hProcess, (LPCVOID)dwAddr, &mi, sizeof(mi));
memcpy(&miBlock[nCount++], &mi, sizeof(mi));
dwAddr += mi.RegionSize;
if((mi.State & MEM_FREE) && mi.RegionSize > nMaxSize)
nMaxSize = mi.RegionSize;
} while(dwAddr < (DWORD)info.lpMaximumApplicationAddress);
p = malloc(nMaxSize);
………..
}
#p#副标题#e#
获得的nMaxSize = 0x34c1 0000,可是内存分派失败,么回事?跟踪一下malloc的执行进程 ,发此刻执行进程中有这样的调解:
blockSize = sizeof(_CrtMemBlockHeader) + nSize + nNoMansLandSize;
颠末这样的调解,blockSize就酿成了0x34c1 0024,所以分派失败。
我们将这 个巨细略作调解:
p = malloc(nMaxSize – 0x24);
照旧分派失败。
想想,假如windows 要将一个空闲块用作heap,那么想必必要写入一些帮助信息,咱再把这个巨细调小一点:
p = malloc(nMaxSize – 0x124);
哈哈,终于乐成了!咱终于分派了885M的内存。
难怪windows 要将这些系统DLL只管往高处放!
一气呵成,咱建设一个最简朴的console application,这样就没有 太多的DLL来举办滋扰。再运行上面的代码,这样可以获得一个最大的内存块巨细0x6c4d d000,期望能 够直接分派,可是——–失败了!
思量windows的内存块分派是以0x10000举办对齐的,实验分派 0x6c4d0000,这回可算乐成了,哈哈,咱就有了1.8G的空间!可是malloc函数的执行进程超慢,过了足 足十几秒才分派乐成,不知道它到底还要做些什么事情。并且其它措施的运行就此酿成蜗牛速度,呵呵 。
顺带说一下,俺只有2G内存。