experiment : 在私有堆和默认进程堆中, 测试能分配的堆空间总和, 每次能分配的最大堆空间
实验环境: Win7X64Sp1 + vs2008, 物理内存16GB.
实验结论:
* 进程堆的最大Size并没有使用完剩余的物理内存
* 每次能分配的最大堆空间接近2M, 不管是私有堆,还是进程堆, 和堆初始Size无关,
* 将堆空间用尽后, 累计堆空间总Size接近2000MB, 不管是私有堆,还是进程堆, 和堆初始Size无关,
- /// @file getHeapSize.cpp
- /// @brief 尝试得到本进程堆的最大size
- #include "stdafx.h"
- #include <Windows.h>
- #include <tchar.h>
- #define MEMORY_REQUESTED_MB (1024 * 1024) ///< 请求的堆尺寸单位(MB)
- size_t GetSystemPageSize();
- bool GetHeapSize(HANDLE hHeap, size_t & nSizeHeapOnce, size_t & nSizeHeap);
- bool GetHeapAllocTotal(HANDLE hHeap, size_t nSizeHeapOnce, size_t & nSizeHeapTotal); ///< 计算在堆上能分配的空间总和
- int _tmain(int argc, _TCHAR* argv[])
- {
- bool bRc = false;
- int iIndex = 0;
- size_t nSizeHeap = 0;
- size_t nSizeHeapOnce = 0;
- size_t nSizeHeapTotal = 0;
- HANDLE hHeap = GetProcessHeap();
- _tprintf(L"when hHeap = GetProcessHeap();\n");
- for(iIndex = 0; iIndex < 5; iIndex++)
- {
- bRc = GetHeapSize(hHeap, nSizeHeapOnce, nSizeHeap);
- _tprintf( L"GetHeapSize() = %s, nSizeHeap = 0x%X, %.3f(MB)\n",
- bRc ? L"TRUE" : L"FALSE",
- nSizeHeap, 1.0f * nSizeHeap / MEMORY_REQUESTED_MB);
- }
- /// 对私有堆的测试
- nSizeHeap = MEMORY_REQUESTED_MB * 10;
- hHeap = HeapCreate(0, GetSystemPageSize() * 4, nSizeHeap); ///< 建立10MB的私有堆, 每次提交4Page
- if(NULL == hHeap)
- _tprintf(L"HeapCreate error code = 0x%x\n", GetLastError());
- else
- {
- _tprintf(L"HeapCreate Ok, nSizeHeap = %dMB\n", nSizeHeap / MEMORY_REQUESTED_MB);
- for(iIndex = 0; iIndex < 5; iIndex++)
- {
- bRc = GetHeapSize(hHeap, nSizeHeapOnce, nSizeHeap);
- _tprintf( L"GetHeapSize() = %s, nSizeHeap = 0x%X, %.3f(MB)\n",
- bRc ? L"TRUE" : L"FALSE",
- nSizeHeap, 1.0f * nSizeHeap / MEMORY_REQUESTED_MB);
- }
- HeapDestroy(hHeap);
- }
- /// 测试从私有堆上能分配的最大空间, 依次分配一块, 计算能分配的空间总和
- nSizeHeap = MEMORY_REQUESTED_MB * 10;
- if(0 == nSizeHeapOnce)
- nSizeHeapOnce = GetSystemPageSize();
- _tprintf(L"nSizeHeapOnce = 0x%x\n", nSizeHeapOnce);
- hHeap = HeapCreate(0, nSizeHeapOnce, nSizeHeap); ///< 建立10MB的私有堆, 每次提交4Page
- if(NULL == hHeap)
- _tprintf(L"HeapCreate error code = 0x%x\n", GetLastError());
- else
- {
- _tprintf(L"HeapCreate Ok, nSizeHeap = %dMB\n", nSizeHeap / MEMORY_REQUESTED_MB);
- bRc = GetHeapAllocTotal(hHeap, nSizeHeapOnce, nSizeHeapTotal);
- _tprintf( L"GetHeapAllocTotal() = %s, nSizeHeapOnce = 0x%X, %.3f(MB), nSizeHeapTotal = 0x%X, %.3f(MB)\n",
- bRc ? L"TRUE" : L"FALSE",
- nSizeHeapOnce, 1.0f * nSizeHeapOnce / MEMORY_REQUESTED_MB,
- nSizeHeapTotal, 1.0f * nSizeHeapTotal / MEMORY_REQUESTED_MB);
- HeapDestroy(hHeap);
- }
- /** operating results
- 将程序编译成Release + win32, 在IDE外直接运行
- when hHeap = GetProcessHeap();
- GetHeapSize() = TRUE, nSizeHeap = 0x70CBF000, 1804.746(MB)
- GetHeapSize() = TRUE, nSizeHeap = 0x70CBF000, 1804.746(MB)
- GetHeapSize() = TRUE, nSizeHeap = 0x70CBF000, 1804.746(MB)
- GetHeapSize() = TRUE, nSizeHeap = 0x70CBF000, 1804.746(MB)
- GetHeapSize() = TRUE, nSizeHeap = 0x70CBF000, 1804.746(MB)
- HeapCreate Ok, nSizeHeap = 10MB
- GetHeapSize() = TRUE, nSizeHeap = 0x1FF000, 1.996(MB)
- GetHeapSize() = TRUE, nSizeHeap = 0x1FF000, 1.996(MB)
- GetHeapSize() = TRUE, nSizeHeap = 0x1FF000, 1.996(MB)
- GetHeapSize() = TRUE, nSizeHeap = 0x1FF000, 1.996(MB)
- GetHeapSize() = TRUE, nSizeHeap = 0x1FF000, 1.996(MB)
- nSizeHeapOnce = 0x1ff000
- HeapCreate Ok, nSizeHeap = 10MB
- GetHeapAllocTotal() = TRUE, nSizeHeapOnce = 0x1FF000, 1.996(MB), nSizeHeapTotal
- = 0x7C41C000, 1988.109(MB)
- 剩余物理内存是8655M, 看来进程堆的最大Size并没有使用完剩余的物理内存
- 经过多次实验, 进程堆的Size大约是1800上下几MB
- 建立10MB的私有堆, 测试出的私有堆大小为2MB左右??
- 建立了20MB的私有堆, 测试出的私有堆大小也为2MB左右.
- 建立了100MB的私有堆, 测试出的私有堆大小也为2MB左右.
- 结论: 进程私有堆是程序编译时指定的, 指定多大都没用
- 在vs2008中设置对大小为10MB, 10485760
- 设置步骤: vs2008工程属性 >> Configuration Properties >> Linker >> System >> Heap Reserver Size
- 实验结果:
- * 每次能分配的堆空间一直2M左右, 不管是私有堆,还是进程堆, 和堆初始Size无关,
- * 能分配的堆空间总和接近2000MB, 不管是私有堆,还是进程堆, 和堆初始Size无关,
- */
- getchar();
- return 0;
- }
- bool GetHeapAllocTotal(HANDLE hHeap, size_t nSizeHeapOnce, size_t & nSizeHeapTotal)
- {
- bool bRc = false;
- BYTE * pBufHeap = NULL;
- nSizeHeapTotal = 0;
- do
- {
- pBufHeap = static_cast<BYTE *>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nSizeHeapOnce));
- if(NULL != pBufHeap)
- {
- bRc = true;
- nSizeHeapTotal += nSizeHeapOnce;
- }
- } while (NULL != pBufHeap);
- return bRc;
- }
- bool GetHeapSize(HANDLE hHeap, size_t & nSizeHeapOnce, size_t & nSizeHeap)
- {
- bool bRc = false;
- size_t nSystemPageSize = GetSystemPageSize();
- int iMultiple = 0; ///< 内存申请容量是SYSTEM_INFO.PageSize的倍数
- BYTE * pBufHeap = NULL;
- iMultiple = static_cast<size_t>(MEMORY_REQUESTED_MB) / nSystemPageSize;
- nSizeHeap = iMultiple * nSystemPageSize; ///< 从1MB开始尝试
- do
- {
- pBufHeap = static_cast<BYTE *>(HeapAlloc(hHeap, HEAP_ZERO_MEMORY, nSizeHeap));
- if(NULL != pBufHeap)
- {
- if(FALSE == HeapFree(GetProcessHeap(), 0, pBufHeap))
- return false;
- }
- iMultiple *= 2; ///< 快速靠近堆上限制
- nSizeHeap = iMultiple * nSystemPageSize;
- } while (NULL != pBufHeap); ///< 一直尝试到失败为止
- /// 从失败的最大Size往小申请, 第一次成功的Size就是进程堆的Size
- nSizeHeap = --iMultiple * nSystemPageSize;
- do
- {
- pBufHeap = static_cast<BYTE *>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nSizeHeap));
- if(NULL != pBufHeap)
- {
- if(FALSE == HeapFree(GetProcessHeap(), 0, pBufHeap))
- {
- return false;
- }
- bRc = true;
- nSizeHeapOnce = nSizeHeap;
- break;
- }
- nSizeHeap = --iMultiple * nSystemPageSize;
- } while (NULL == pBufHeap); ///< 一直尝试到成功为止
- return bRc;
- }
- size_t GetSystemPageSize()
- {
- /// SYSTEM_INFO.dwPageSize : 页面大小和页保护和承诺的粒度, 是VirtualAlloc的入参
- SYSTEM_INFO sSysInfo;
- GetSystemInfo(&sSysInfo);
- return sSysInfo.dwPageSize;
- }
http://blog.csdn.net/lostspeed/article/details/8423215
experiment : 在私有堆和默认进程堆中, 测试能分配的堆空间总和, 每次能分配的最大堆空间的更多相关文章
- 栈 堆 stack heap 堆内存 栈内存 内存分配中的堆和栈 掌握堆内存的权柄就是返回的指针 栈是面向线程的而堆是面向进程的。 new/delete and malloc/ free 指针与内存模型
小结: 1.栈内存 为什么快? Due to this nature, the process of storing and retrieving data from the stack is ver ...
- (适合入门)JVM堆内存相关的启动参数:年轻一代、岁和永久代内存分配
假设你要观察JVM进程消耗的堆内存,通过命令工具jmap或可视化工具jvisualvm.exe.JVM这些参数的默认启动值.假设你想知道JVM内存分配策略,最开始手动设置这些参数.通过JDK统计结果, ...
- Java堆和栈的区别和介绍,JVM的堆和栈
一.Java的堆内存和栈内存 Java把内存划分成两种:一种是堆内存,一种是栈内存. 堆:主要用于存储实例化的对象,数组.由JVM动态分配内存空间.一个JVM只有一个堆内存,线程是可以共享数据的. ...
- JVM内存结构之堆、栈、方法区以及直接内存、堆和栈区别
JVM内存结构之堆.栈.方法区以及直接内存.堆和栈区别 一. 理解JVM中堆与栈以及方法区 堆(heap):FIFO(队列优先,先进先出):二级缓存:*JVM中只有一个堆区被所有线程所共享:对象和数 ...
- new 的对象如何不分配在堆而分配在栈上(方法逃逸等)
当能够明确对象不会发生逃逸时,就可以对这个对象做一个优化,不将其分配到堆上,而是直接分配到栈上,这样在方法结束时,这个对象就会随着方法的出栈而销毁,这样就可以减少垃圾回收的压力. 如方法逃逸. 逃逸分 ...
- iOS程序中的内存分配 栈区堆区全局区
在计算机系统中,运行的应用程序的数据都是保存在内存中的,不同类型的数据,保存的内存区域不同.一.内存分区 栈区(stack) 由编译器自动分配并释放,存放函数的参数值,局部变量等.栈是系统数据结构,对 ...
- iOS开发中的内存分配(堆和栈)
进程的内存分区 所有进程(执行的程序)都必须占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是存放取自用户输入的数据等等.不过进程对这些内存的管理方式因内存用途不一而不尽相同,有些内存是事先 ...
- (转)在.NET程序运行过程中,什么是堆,什么是栈?什么情况下会在堆(栈)上分配数据?它们有性能上的区别吗?“结构”对象可能分配在堆上吗?什么情况下会发生,有什么需要注意的吗?
转自:http://www.cnblogs.com/xiaoyao2011/archive/2011/09/09/2172427.html 在.NET程序运行过程中,什么是堆,什么是栈? 堆也就是托管 ...
- NET的堆和栈04,对托管和非托管资源的垃圾回收以及内存分配
在" .NET的堆和栈01,基本概念.值类型内存分配"中,了解了"堆"和"栈"的基本概念,以及值类型的内存分配.我们知道:当执行一个方法的时 ...
随机推荐
- usr/bin/mysqladmin: refresh failed; error: 'Unknown error'
debian wheezy 升级后, 由于授权错误, 导致password给改动, 在debian的mysql safe下也无法进入. 我在/etc/mysql/my.cnf 里面已经改动了bin ...
- 算法 Tricks(三)—— 数组(序列)任意区间最小(大)值
序列(数组)的区间通过左右端点确定,这样首先设置一个最值变量用来记录最值,从左端点一步步移动到右端点,自然移动的过程中也可以计算整个区间的和,也即一次线性遍历下来,可同时获得多个有用信息. // 区间 ...
- Springboot + shiro 整合之Url拦截设置(转)
shiro 整合到springboot 还是比较简单的,只需要新建一个spring-shiro.xml的配置文件: <span style="font-size:14px;" ...
- UI组件之AdapterView及其子类关系,Adapter接口及事实上现类关系
AdapterView本身是一个抽象基类,它派生的的子类在使用方法上十分类似.AdapterView直接派生的三个子类:AbsListView.AbsSpinner,AdapterViewAnimat ...
- JavaScript对象的创建
原文 简书原文:https://www.jianshu.com/p/6cb1e7b7e379 大纲 前言 1.简单方式创建对象的方法 2.工厂模式创建对象 3.构造函数模式创建对象 4.原型模式创建对 ...
- ZOJ FatMouse' Trade 贪心
得之我幸,不得,我命.仅此而已. 学姐说呀,希望下次看到你的时候依然潇洒如故.(笑~) 我就是这么潇洒~哈哈. 感觉大家比我还紧张~ 我很好的.真的 ------------------------- ...
- Android官方数据绑定框架DataBinding(一)
还记得在博客<高逼格UI-ASD(Android Support Design)>的開始曾经说过,Android最新推出了一个官方的数据绑定框架-Data Binding Library. ...
- php中usort自定义排序如何使用
php中usort自定义排序如何使用 一.总结 一句话总结:多写一个规则函数,而这个函数的写法和普通函数一样,调用的时候规则函数用函数名的字符串. 1.用户自定义规则函数有哪三个? usort — 使 ...
- TF-IDF模型
TF-IDF模型 1. 理论基础 由于数据挖掘所有数据都要以数字形式存在,而文本是以字符串形式存在.所以进行文本挖掘时需要先对字符串进行数字化,从而能够进行计算.TF-IDF就是这样一种技术,能够将字 ...
- 【34.14%】【BZOJ 3110】 [Zjoi2013]K大数查询
Time Limit: 20 Sec Memory Limit: 512 MB Submit: 5375 Solved: 1835 [Submit][Status][Discuss] Descript ...