zoukankan      html  css  js  c++  java
  • experiment : 在私有堆和默认进程堆中, 测试能分配的堆空间总和, 每次能分配的最大堆空间

    实验环境: Win7X64Sp1 + vs2008,  物理内存16GB.

    实验结论:

        *  进程堆的最大Size并没有使用完剩余的物理内存
        *  每次能分配的最大堆空间接近2M, 不管是私有堆,还是进程堆, 和堆初始Size无关, 
        *  将堆空间用尽后, 累计堆空间总Size接近2000MB, 不管是私有堆,还是进程堆, 和堆初始Size无关,

    [cpp] view plain copy
     
      1. /// @file       getHeapSize.cpp  
      2. /// @brief      尝试得到本进程堆的最大size  
      3.   
      4. #include "stdafx.h"  
      5. #include <Windows.h>  
      6. #include <tchar.h>  
      7.   
      8. #define MEMORY_REQUESTED_MB (1024 * 1024)       ///< 请求的堆尺寸单位(MB)  
      9. size_t  GetSystemPageSize();  
      10. bool    GetHeapSize(HANDLE hHeap, size_t & nSizeHeapOnce, size_t & nSizeHeap);  
      11. bool    GetHeapAllocTotal(HANDLE hHeap, size_t nSizeHeapOnce, size_t & nSizeHeapTotal); ///< 计算在堆上能分配的空间总和  
      12.   
      13. int _tmain(int argc, _TCHAR* argv[])  
      14. {  
      15.     bool    bRc             =   false;  
      16.     int     iIndex          =   0;  
      17.     size_t  nSizeHeap       =   0;  
      18.     size_t  nSizeHeapOnce   =   0;  
      19.     size_t  nSizeHeapTotal  =   0;  
      20.     HANDLE  hHeap           =   GetProcessHeap();  
      21.   
      22.     _tprintf(L"when hHeap = GetProcessHeap(); ");  
      23.     for(iIndex = 0; iIndex < 5; iIndex++)  
      24.     {  
      25.         bRc = GetHeapSize(hHeap, nSizeHeapOnce, nSizeHeap);  
      26.         _tprintf(   L"GetHeapSize() = %s, nSizeHeap = 0x%X, %.3f(MB) ",   
      27.             bRc ? L"TRUE" : L"FALSE",   
      28.             nSizeHeap, 1.0f * nSizeHeap / MEMORY_REQUESTED_MB);  
      29.     }  
      30.   
      31.     /// 对私有堆的测试  
      32.     nSizeHeap = MEMORY_REQUESTED_MB * 10;  
      33.     hHeap = HeapCreate(0, GetSystemPageSize() * 4, nSizeHeap);  ///< 建立10MB的私有堆, 每次提交4Page  
      34.     if(NULL == hHeap)  
      35.         _tprintf(L"HeapCreate error code = 0x%x ", GetLastError());  
      36.     else  
      37.     {  
      38.         _tprintf(L"HeapCreate Ok, nSizeHeap = %dMB ", nSizeHeap / MEMORY_REQUESTED_MB);  
      39.         for(iIndex = 0; iIndex < 5; iIndex++)  
      40.         {  
      41.             bRc = GetHeapSize(hHeap, nSizeHeapOnce, nSizeHeap);  
      42.             _tprintf(   L"GetHeapSize() = %s, nSizeHeap = 0x%X, %.3f(MB) ",   
      43.                 bRc ? L"TRUE" : L"FALSE",   
      44.                 nSizeHeap, 1.0f * nSizeHeap / MEMORY_REQUESTED_MB);  
      45.         }  
      46.   
      47.         HeapDestroy(hHeap);  
      48.     }  
      49.   
      50.     /// 测试从私有堆上能分配的最大空间, 依次分配一块, 计算能分配的空间总和  
      51.     nSizeHeap = MEMORY_REQUESTED_MB * 10;  
      52.     if(0 == nSizeHeapOnce)  
      53.         nSizeHeapOnce = GetSystemPageSize();  
      54.     _tprintf(L"nSizeHeapOnce = 0x%x ", nSizeHeapOnce);  
      55.   
      56.     hHeap = HeapCreate(0, nSizeHeapOnce, nSizeHeap);    ///< 建立10MB的私有堆, 每次提交4Page  
      57.     if(NULL == hHeap)  
      58.         _tprintf(L"HeapCreate error code = 0x%x ", GetLastError());  
      59.     else  
      60.     {  
      61.         _tprintf(L"HeapCreate Ok, nSizeHeap = %dMB ", nSizeHeap / MEMORY_REQUESTED_MB);  
      62.         bRc = GetHeapAllocTotal(hHeap, nSizeHeapOnce, nSizeHeapTotal);  
      63.         _tprintf(   L"GetHeapAllocTotal() = %s, nSizeHeapOnce = 0x%X, %.3f(MB), nSizeHeapTotal = 0x%X, %.3f(MB) ",   
      64.             bRc ? L"TRUE" : L"FALSE",   
      65.             nSizeHeapOnce, 1.0f * nSizeHeapOnce / MEMORY_REQUESTED_MB,  
      66.             nSizeHeapTotal, 1.0f * nSizeHeapTotal / MEMORY_REQUESTED_MB);  
      67.   
      68.         HeapDestroy(hHeap);  
      69.     }  
      70.       
      71.   
      72.     /** operating results 
      73.     将程序编译成Release + win32, 在IDE外直接运行 
      74.  
      75.     when hHeap = GetProcessHeap(); 
      76.     GetHeapSize() = TRUE, nSizeHeap = 0x70CBF000, 1804.746(MB) 
      77.     GetHeapSize() = TRUE, nSizeHeap = 0x70CBF000, 1804.746(MB) 
      78.     GetHeapSize() = TRUE, nSizeHeap = 0x70CBF000, 1804.746(MB) 
      79.     GetHeapSize() = TRUE, nSizeHeap = 0x70CBF000, 1804.746(MB) 
      80.     GetHeapSize() = TRUE, nSizeHeap = 0x70CBF000, 1804.746(MB) 
      81.     HeapCreate Ok, nSizeHeap = 10MB 
      82.     GetHeapSize() = TRUE, nSizeHeap = 0x1FF000, 1.996(MB) 
      83.     GetHeapSize() = TRUE, nSizeHeap = 0x1FF000, 1.996(MB) 
      84.     GetHeapSize() = TRUE, nSizeHeap = 0x1FF000, 1.996(MB) 
      85.     GetHeapSize() = TRUE, nSizeHeap = 0x1FF000, 1.996(MB) 
      86.     GetHeapSize() = TRUE, nSizeHeap = 0x1FF000, 1.996(MB) 
      87.     nSizeHeapOnce = 0x1ff000 
      88.     HeapCreate Ok, nSizeHeap = 10MB 
      89.     GetHeapAllocTotal() = TRUE, nSizeHeapOnce = 0x1FF000, 1.996(MB), nSizeHeapTotal 
      90.     = 0x7C41C000, 1988.109(MB) 
      91.  
      92.     剩余物理内存是8655M, 看来进程堆的最大Size并没有使用完剩余的物理内存 
      93.     经过多次实验, 进程堆的Size大约是1800上下几MB 
      94.  
      95.     建立10MB的私有堆, 测试出的私有堆大小为2MB左右?? 
      96.     建立了20MB的私有堆, 测试出的私有堆大小也为2MB左右. 
      97.     建立了100MB的私有堆, 测试出的私有堆大小也为2MB左右. 
      98.  
      99.     结论: 进程私有堆是程序编译时指定的, 指定多大都没用 
      100.  
      101.     在vs2008中设置对大小为10MB, 10485760 
      102.     设置步骤: vs2008工程属性 >> Configuration Properties >> Linker >> System >> Heap Reserver Size 
      103.     实验结果:  
      104.         * 每次能分配的堆空间一直2M左右, 不管是私有堆,还是进程堆, 和堆初始Size无关,  
      105.         * 能分配的堆空间总和接近2000MB, 不管是私有堆,还是进程堆, 和堆初始Size无关, 
      106.     */  
      107.   
      108.     getchar();  
      109.     return 0;  
      110. }  
      111.   
      112. bool    GetHeapAllocTotal(HANDLE hHeap, size_t nSizeHeapOnce, size_t & nSizeHeapTotal)  
      113. {  
      114.     bool        bRc             =   false;  
      115.     BYTE *      pBufHeap        =   NULL;  
      116.   
      117.     nSizeHeapTotal = 0;  
      118.     do   
      119.     {  
      120.         pBufHeap = static_cast<BYTE *>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nSizeHeapOnce));  
      121.         if(NULL != pBufHeap)  
      122.         {  
      123.             bRc = true;  
      124.             nSizeHeapTotal += nSizeHeapOnce;  
      125.         }  
      126.   
      127.     } while (NULL != pBufHeap);  
      128.   
      129.     return bRc;  
      130. }  
      131.   
      132. bool    GetHeapSize(HANDLE hHeap, size_t & nSizeHeapOnce, size_t & nSizeHeap)  
      133. {  
      134.     bool        bRc             =   false;  
      135.     size_t      nSystemPageSize =   GetSystemPageSize();  
      136.     int         iMultiple       =   0;          ///< 内存申请容量是SYSTEM_INFO.PageSize的倍数  
      137.     BYTE *      pBufHeap        =   NULL;  
      138.   
      139.     iMultiple = static_cast<size_t>(MEMORY_REQUESTED_MB) / nSystemPageSize;  
      140.     nSizeHeap = iMultiple * nSystemPageSize;    ///< 从1MB开始尝试  
      141.     do   
      142.     {  
      143.         pBufHeap = static_cast<BYTE *>(HeapAlloc(hHeap, HEAP_ZERO_MEMORY, nSizeHeap));  
      144.         if(NULL != pBufHeap)  
      145.         {  
      146.             if(FALSE == HeapFree(GetProcessHeap(), 0, pBufHeap))  
      147.                 return false;  
      148.         }  
      149.   
      150.         iMultiple *= 2; ///< 快速靠近堆上限制  
      151.         nSizeHeap = iMultiple * nSystemPageSize;  
      152.     } while (NULL != pBufHeap); ///< 一直尝试到失败为止  
      153.   
      154.     /// 从失败的最大Size往小申请, 第一次成功的Size就是进程堆的Size  
      155.     nSizeHeap = --iMultiple * nSystemPageSize;  
      156.     do   
      157.     {  
      158.         pBufHeap = static_cast<BYTE *>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nSizeHeap));  
      159.         if(NULL != pBufHeap)  
      160.         {  
      161.             if(FALSE == HeapFree(GetProcessHeap(), 0, pBufHeap))  
      162.             {  
      163.                 return false;  
      164.             }  
      165.   
      166.             bRc = true;  
      167.             nSizeHeapOnce = nSizeHeap;   
      168.             break;  
      169.         }  
      170.   
      171.         nSizeHeap = --iMultiple * nSystemPageSize;  
      172.     } while (NULL == pBufHeap); ///< 一直尝试到成功为止  
      173.   
      174.     return bRc;  
      175. }  
      176.   
      177. size_t  GetSystemPageSize()  
      178. {  
      179.     /// SYSTEM_INFO.dwPageSize : 页面大小和页保护和承诺的粒度, 是VirtualAlloc的入参  
      180.   
      181.     SYSTEM_INFO sSysInfo;  
      182.   
      183.     GetSystemInfo(&sSysInfo);  
      184.     return sSysInfo.dwPageSize;  
      185. }  

    http://blog.csdn.net/lostspeed/article/details/8423215

  • 相关阅读:
    发现另一种简便的完全居中css写法 element.style { width: 500px; height: 200px; background: #eee; position: absolute; margin: auto; top: 0; left: 0; bottom: 0; right: 0; }
    子网掩码随笔
    C# MVC网站自动由HTTP转为HTTPS
    c++中的void*
    权利的游戏
    字符串
    字符串
    权利的游戏 S0803
    加权有向图
    加权无向图
  • 原文地址:https://www.cnblogs.com/findumars/p/8317975.html
Copyright © 2011-2022 走看看