我们都知道在程序里可以使用malloc在堆上分配内存,显然windows应该为这个Heap分配一块空间的,我们在主程序里用malloc分配一小块内存,看看指针指向哪里:
char* p = (char*)malloc(10);
得到一个指针:0x00b267b0
在内存块里面找,很容易就发现了目标:
基址 | 分配基址 | 分配保护 | 大小 | 状态 | 保护 | 类型 |
00b20000 | 00b20000 | 00000004 PAGE_READWRITE | 00007000 | 00001000 MEM_COMMIT | 00000004 PAGE_READWRITE | 00020000 MEM_PRIVATE |
00b27000 | 00b20000 | 00000004 PAGE_READWRITE | 00009000 | 00002000 MEM_RESERVE | 00000000 | 00020000 MEM_PRIVATE |
从这里可以发现malloc采用的算法并不会在一开始就分配一块很大的内存,如果我们接着用:
p = (char*)malloc(0x10000);
分配一块64K的内存,这时可以发现又多了一块内存:
基址 | 分配基址 | 分配保护 | 大小 | 状态 | 保护 | 类型 |
00cd0000 | 00cd0000 | 00000004 PAGE_READWRITE | 00012000 | 00001000 MEM_COMMIT | 00000004 PAGE_READWRITE | 00020000 MEM_PRIVATE |
00ce2000 | 00cd0000 | 00000004 PAGE_READWRITE | 000ee000 | 00002000 MEM_RESERVE | 00000000 | 00020000 MEM_PRIVATE |
而这块内存在第一次分配时是空闲的。
由此可以猜测,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);
………..
}
得到的nMaxSize = 0x34c1 0000,但是内存分配失败,么回事?跟踪一下malloc的执行过程,发现在执行过程中有这样的调整:
blockSize = sizeof(_CrtMemBlockHeader) + nSize + nNoMansLandSize;
经过这样的调整,blockSize就变成了0x34c1 0024,所以分配失败。
我们将这个大小略作调整:
p = malloc(nMaxSize – 0x24);
还是分配失败。
想想,如果windows要将一个空闲块用作heap,那么想必需要写入一些辅助信息,咱再把这个大小调小一点:
p = malloc(nMaxSize – 0x124);
哈哈,终于成功了!咱终于分配了885M的内存。
难怪windows要将这c系统DLL尽量往高处放!
趁热打铁,咱创建一个最简单的console application,这样就没有太多的DLL来进行干扰。再运行上面的代码,这样可以得到一个最大的内存块大小0x6c4d d000,期望能够直接分配,但是--------失败了!
考虑windows的内存块分配是以0x10000进行对齐的,尝试分配0x6c4d0000,这回可算成功了,哈哈,咱就有了1.8G的空间!但是malloc函数的执行过程超慢,过了足足十几秒才分配成功,不知道它到底还要做些什么工作。而且其它程序的运行就此变成蜗牛速度,呵呵。
顺带说一下,俺只有2G内存。
编缉推荐阅读以下文章
版权与免责声明
1、本站所发布的文章仅供技术交流参考,本站不主张将其做为决策的依据,浏览者可自愿选择采信与否,本站不对因采信这些信息所产生的任何问题负责。
2、本站部分文章来源于网络,其版权为原权利人所有。由于来源之故,有的文章未能获得作者姓名,署“未知”或“佚名”。对于这些文章,有知悉作者姓名的请告知本站,以便及时署名。如果作者要求删除,我们将予以删除。除此之外本站不再承担其它责任。
3、本站部分文章来源于本站原创,本站拥有所有权利。
4、如对本站发布的信息有异议,请联系我们,经本站确认后,将在三个工作日内做出修改或删除处理。
请参阅权责声明!