VirtualAlloc 一次分配 1PAGE 以上的 RAM. 每次分配都是 PAGE 的整数倍. 你不会想为了分配 1 个 BYTE 的空间而浪费剩下的 4095 字节. OK, 你可以自己写算法, 多分配几 PAGE. 然后每次分配少量数据时就从那几 PAGE 中划分出来. KERNEL32 提供了一个解决办法, 用 HeapAlloc/GlobalAlloc 分配 RAM. 这样, KERNEL32 帮助完成分配动作, 并且尽量在减少用于跟踪空闲区域和已占用区域消耗的数据结构.

很久以前也有个产品叫做 WINDOWS. 那时候的 WINDOWS 是 16BIT 的, 地址空间有些紧俏, 有钱不够, 还需要粮票肉票才能拿到. 你已经调用 GlobalAlloc 和已经出钱的性质一样. GlobalAlloc 还不够, 有时候需要 GlocalLock 才能确定你的东西确实可以拿到手, 不然你的指针会非法, 被充公, 你的应用会被杀头. 扯远了. 后来 OS 进化了, 觉得可以取消粮票肉票, 但是你必须用新版钞票才行. 那就是 HeapAlloc. 只要市场上的 RAM 数量没问题, 你的 HeapAlloc 没问题, 那就总能拿到东西. 但是, 你总不能说有了 2000 版的钞票, 那 80 版的马上作废啊, 那 GlobalAlloc 也只好继续流通下去. 至于可以流通到什么时候, 没人知道.

GlobalAlloc 和 LocalAlloc 都是 Windows 系统提供的内存分配函数, 他们的区别源于 16BIT 代码时代, 那时没有不同的进程内存空间, GlobalAlloc 是在全局的, 公用的远堆上分配; LocalAlloc 则在任务自己的近堆上分配. 在 Win32 平台下这两个函数是完全相同的, 都是在进程自己的内存空间中分配, Lock 之后的结果是普通指针(32位近指针).  new 与它们的区别未免太大, 因为与 C++ 的构造函数和异常机制有关. 一般编译器中的 new 都是用 malloc 来分配内存的. 用 malloc 与其它两个函数比较应该更合理. 一般 malloc 的实现并不是从系统的堆中分配的, 而是从编译器连接的运行库自己管理的堆中, 在 Win32 平台上的开发工具的编译结果中, 通常是用 HeapCreate 创建一个堆, 用 HeapAlloc 和 HeapRealloc 维护堆的空间增长, 在最后用 HeapDestroy 删除堆. 而在用 malloc 分配, 用 free 释放时则由运行库的代码负责从这个堆中分配空间和向这个堆中归还空间, 并维护这个堆中的数据结构. 由于 malloc 堆的管理是由运行库自己管理的, 所在当我们使用静态运行库时, 如果在一个 DLL 中用 malloc 分配了内存而在另一个 DLL 中用 free 去释放它, 通常都会产生问题. 这是因为每个DLL都连接了一份运行库的代码, 从而也都有一个自己的局部堆, 而在用 free 释放时它会假设这块内存是在自己的堆中分配的, 从而导致错误. 而通过 GlobalAlloc 和 LocalAlloc 分配的内存不存在这个问题.

HeapCreate 就已经完成了创建堆的操作. HeapAlloc, HeapReAlloc 和 HeapFree 都是从这个堆中分配, 释放内存的函数. 也就是说, Windows 系统其实已经为我们提供了完整的一套使用自己的局部堆的操作, 不过没有看到指定分配策略的方法. 根据编译器提供的源代码来 看, VC 中的 malloc, realloc 和 free 等函数主要功能就是用这几个 API 函数来实现的, 而 BC 中的实现相当复杂, 似乎是维护了一套自己的逻辑. 据说 BC 的内存分配比 VC 快, 大概是这个原因.

HeapAlloc 和 GlobalAlloc 以及 VirtualAlloc 三者之间的关系(转)的更多相关文章

  1. silverlight Canvas、StackPanel、Grid三者之间的关系

    学习 silverlight   首先Canvas.StackPanel.Grid 博客园里看到jailu的这篇文章整理得很好 贴下来: Silverlight提供了非常灵活的布局管理系统,让程序员和 ...

  2. 电脑结构和CPU、内存、硬盘三者之间的关系

    前面提到了,电脑之父——冯·诺伊曼提出了计算机的五大部件:输入设备.输出设备.存储器.运算器和控制器. 我们看一下现在我们电脑的: 键盘鼠标.显示器.机箱.音响等等. 这里显示器为比较老的CRT显示器 ...

  3. 【Linux网络编程】TCP网络编程中connect()、listen()和accept()三者之间的关系

    [Linux网络编程]TCP网络编程中connect().listen()和accept()三者之间的关系 基于 TCP 的网络编程开发分为服务器端和客户端两部分,常见的核心步骤和流程如下: conn ...

  4. 网络互联技术(2)——前篇—【转载】电脑结构和CPU、内存、硬盘三者之间的关系

    原文链接:传送门 详细内容: 电脑结构和CPU.内存.硬盘三者之间的关系 前面提到了,电脑之父——冯·诺伊曼提出了计算机的五大部件:输入设备.输出设备.存储器.运算器和控制器. 我们看一下现在我们电脑 ...

  5. 转:spring data jpa、 hibernate、 jpa 三者之间的关系

    原文链接:spring data jpa. hibernate. jpa 三者之间的关系 spring data jpa hibernate jpa 三者之间的关系 JPA规范与ORM框架之间的关系是 ...

  6. 程序中try、throw、catch三者之间的关系

    c++程序中,采用一种专门的结构化处理逻辑的异常处理机制. 1.try语句 try语句块的作用是启动异常处理机制,检测try语句块中程序语句执行时可能出现的异常. try语句块总是与catch一同出现 ...

  7. Window系统、主函数和窗体函数这三者之间的关系

    理解Window系统.主窗体.窗体函数这三者之间的关系,对于编写Windows程序十分重要. 主函数和窗体函数都是由Windows系统来调用的函数.仅仅只是主函数是程序启动之后.系统首先调用的函数: ...

  8. 5.Javascript 原型链之原型对象、实例和构造函数三者之间的关系

    前言:用了这么久js,对于它的原型链一直有种模糊的不确切感,很不爽,隧解析之. 本文主要解决的问题有以下三个: (1)constructor 和 prototype 以及实例之间啥关系? (2)pro ...

  9. 【面向对象】----【prototype&&__proto__&&实例化对象三者之间的关系】(四)-----【巷子】

    1.构造函数 a.什么是构造函数? 解释:通过关键字new 创建的函数叫做构造函数 作用:用来创建一个对象 废话少说直接上代码,首先我们还是创建一个构造函数人类 然后我们在创建两个实例,一个凡尘 一个 ...

随机推荐

  1. python网络编程--线程event

    一:线程event作用 Python提供了Event对象用于线程间通信,它是线程设置的信号标志,如果信号标志位真,则其他线程等待直到信号结束. Event对象实现了简单的线程通信机制,它提供了设置信号 ...

  2. [转] Cacti+Nagios监控平台完美整合

    Cacti+Nagios监控平台完美整合 http://os.51cto.com/art/201411/458006.htm 整合nagios+cacti+微信.飞信实现网络监控报警 http://b ...

  3. jmter提交图片

    jmter提交图片 https://www.cnblogs.com/linglingyuese/p/4514808.html

  4. NOIP2015 D2T3 运输计划

    拿到题目的第一眼 首先这是一棵n个节点的树(别说你看不出来) 然后对于树上的m条链我们可以选取树上的唯一一条边使它的边权变为0 求处理后最长链的长度 20分 m=1好啦,好像可做一眼望去全是水 只需求 ...

  5. Delphi IdTCPClient IdTCPServer 点对点传送文件

    https://blog.csdn.net/luojianfeng/article/details/53959175 2016年12月31日 23:40:15 阅读数:2295 Delphi     ...

  6. 设置Loadrunner负载机临时文件目录

    设置Loadrunner负载机临时文件目录 最近在跑稳定性测试 3 X 24小时的时候,发现负载机产生的日志还运行记录等等竟然有100多G! C盘空间不足,但是D盘还有700多G空间呢,怎么让临时文件 ...

  7. Django实战(20):分页(Pagination)

    在上一节我们实现了针对某个产品的订单订阅功能.但是我们可能需要直接在站点上查询所有的订单.显然,随着时间的增长订单会越来越多,所以分页(Pagination)是个好办法:每次只显示一部分订单. 分页是 ...

  8. 百度地图API--Key的获得

    [开年后花了半个月的时间学习了百度地图API开发,准备投入项目中,学习的过程中写了一些简单的总结,在部门内部做了一个简单的分享培训,这里希望将自己的仅有的一点点关于百度地图API的收获分享给社区,整个 ...

  9. C#.net实现图片上传功能

    C#.NET前台:<asp:Image ID="imgFood" runat="server" /> <asp:FileUpload ID=& ...

  10. 重装Win7后找回Ubuntu启动项并在Ubuntu中修复引导

    1. 输入$ sudo fdisk -l 查看磁盘信息,选择Linux的磁盘,如sda10 2. 输入$ sudo -i(此步用于得到root权限,方便以下操作.) 3. 输入$ mkdir /med ...