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

实验结论:

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

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

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

experiment : 在私有堆和默认进程堆中, 测试能分配的堆空间总和, 每次能分配的最大堆空间的更多相关文章

  1. 栈 堆 stack heap 堆内存 栈内存 内存分配中的堆和栈 掌握堆内存的权柄就是返回的指针 栈是面向线程的而堆是面向进程的。 new/delete and malloc/ free 指针与内存模型

    小结: 1.栈内存 为什么快? Due to this nature, the process of storing and retrieving data from the stack is ver ...

  2. (适合入门)JVM堆内存相关的启动参数:年轻一代、岁和永久代内存分配

    假设你要观察JVM进程消耗的堆内存,通过命令工具jmap或可视化工具jvisualvm.exe.JVM这些参数的默认启动值.假设你想知道JVM内存分配策略,最开始手动设置这些参数.通过JDK统计结果, ...

  3. Java堆和栈的区别和介绍,JVM的堆和栈

    一.Java的堆内存和栈内存 Java把内存划分成两种:一种是堆内存,一种是栈内存.   堆:主要用于存储实例化的对象,数组.由JVM动态分配内存空间.一个JVM只有一个堆内存,线程是可以共享数据的. ...

  4. JVM内存结构之堆、栈、方法区以及直接内存、堆和栈区别

    JVM内存结构之堆.栈.方法区以及直接内存.堆和栈区别 一.  理解JVM中堆与栈以及方法区 堆(heap):FIFO(队列优先,先进先出):二级缓存:*JVM中只有一个堆区被所有线程所共享:对象和数 ...

  5. new 的对象如何不分配在堆而分配在栈上(方法逃逸等)

    当能够明确对象不会发生逃逸时,就可以对这个对象做一个优化,不将其分配到堆上,而是直接分配到栈上,这样在方法结束时,这个对象就会随着方法的出栈而销毁,这样就可以减少垃圾回收的压力. 如方法逃逸. 逃逸分 ...

  6. iOS程序中的内存分配 栈区堆区全局区

    在计算机系统中,运行的应用程序的数据都是保存在内存中的,不同类型的数据,保存的内存区域不同.一.内存分区 栈区(stack) 由编译器自动分配并释放,存放函数的参数值,局部变量等.栈是系统数据结构,对 ...

  7. iOS开发中的内存分配(堆和栈)

    进程的内存分区 所有进程(执行的程序)都必须占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是存放取自用户输入的数据等等.不过进程对这些内存的管理方式因内存用途不一而不尽相同,有些内存是事先 ...

  8. (转)在.NET程序运行过程中,什么是堆,什么是栈?什么情况下会在堆(栈)上分配数据?它们有性能上的区别吗?“结构”对象可能分配在堆上吗?什么情况下会发生,有什么需要注意的吗?

    转自:http://www.cnblogs.com/xiaoyao2011/archive/2011/09/09/2172427.html 在.NET程序运行过程中,什么是堆,什么是栈? 堆也就是托管 ...

  9. NET的堆和栈04,对托管和非托管资源的垃圾回收以及内存分配

    在" .NET的堆和栈01,基本概念.值类型内存分配"中,了解了"堆"和"栈"的基本概念,以及值类型的内存分配.我们知道:当执行一个方法的时 ...

随机推荐

  1. iOS 之应用性能调优的25个建议和技巧

    注意:每在优化代码之前,你都要注意一个问题,不要养成"预优化"代码的错误习惯. 时常使用Instruments去profile你的代码来发现须要提升的方面.Matt Gallowa ...

  2. 彩票案例-frame,center和bounds属性

    控件的属性: 二.frame.center和bounds属性 " 在iOS中,每一个控件都是继承于UIView的.都会有视图的属性存在,控制这个视图的位置就有Frame和Bounds两个属性 ...

  3. POJ 3723 Conscription MST

    http://poj.org/problem?id=3723 题目大意: 需要征募女兵N人,男兵M人,没征募一个人需要花费10000美元,但是如果已经征募的人中有一些关系亲密的人,那么可以少花一些钱, ...

  4. Iceberg使用

    Iceberg是Mac下比較好用的pkg生成工具. 在files中选择你想要存放(自己文件的目录),生成pkg后目录就会存储在设置的那个目录下. 点击scripts选择pkg安装各个阶段所要运行脚本路 ...

  5. TTS-零基础入门之语音模板化

    上篇介绍了TTS的一个简单样例http://blog.csdn.net/u010176014/article/details/47326413 本篇咱们进一步聊聊 语音怎样读模板. 比方 公交车上的模 ...

  6. 10.3、android输入系统_必备Linux编程知识_任意进程双向通信(scoketpair+binder)

    3. 任意进程间通信(socketpair_binder) 进程每执行一次open打开文件,都会在内核中有一个file结构体表示它: 对每一个进程在内核中都会有一个task_struct表示进程,这个 ...

  7. FTP、SSH、NFS等环境工具的安装

    注意:通过ftp互传文件或者通过ssh登录的时候,ubuntu需要使用bridged上网环境 ftp: sudo apt-get install vsftpd sudo vi /etc/vsftpd. ...

  8. 【习题5-5 UVA-10391】Compound Words

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 枚举每一个串的分割点. 看看左右两个串在不在字符串中即可. [代码] #include <bits/stdc++.h> ...

  9. [Ramda] Pluck & Props: Get the prop(s) from object array

    Pluck: Get one prop from the object array: R.pluck(}, {a: }]); //=> [1, 2] R.pluck()([[, ], [, ]] ...

  10. BestCoder Round #11 (Div. 2) 前三题题解

    题目链接: huangjing hdu5054 Alice and Bob 思路: 就是(x,y)在两个參考系中的表示演全然一样.那么仅仅可能在这个矩形的中点.. 题目: Alice and Bob ...