程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> xp下用戶程序空間分配(7):Heap

xp下用戶程序空間分配(7):Heap

編輯:關於C++

我們都知道在程序裡可以使用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);
………..

}

得到的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內存。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved