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. Linux 网络编程实例

    /*socket->bind->listen->accept->recv/recvfrom->send/sendto->close 客户端:socket->c ...

  2. 移动端默认meta标签

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><met ...

  3. [java笔记]动态数组

    private int count;//计数器 private int ary[] = new int [3]; if(count >= ary.length){ //数组动态扩展 int ne ...

  4. IntelliJ IDEA + Maven + Tomcat 本地开发、部署、调试。

    1.maven 下载 解压 配置下 远程仓库( 用阿里云的 比较快).本地仓库 (可以本地C盘建立个文件夹当仓库).环境变量(方便使用maven命令)就可以了. 2.tomcat 下载 解压 配置下 ...

  5. Codeforces 777E - Hanoi Factory(贪心+栈)

    题目链接:http://codeforces.com/problemset/problem/777/E 题意:有n个环给你内环半径.外环半径和高度,叠这些环还要满足以下要求: ①:下面的环的外径要&g ...

  6. Effective STL 43: Prefer algorithm calls to hand-written loops

    Effective STL 43: Prefer algorithm calls to hand-written loops */--> div.org-src-container { font ...

  7. 自定义Adapter为什么会重复多轮调用getView?——原来是ListView.onMeasure在作祟

    相信很多人在使用自定义Adapter的时候都遇到这样的问题: 假设Adapter数据源中只有30个Item,理论上每显示一个新的Item的时候就会调用一次getView,均显示一次的话是要调用getV ...

  8. mongo体系架构学习

    MongoDB是一个可移植的数据库,它在流行的每一个平台上都可以使用,即所谓的跨平台性,在不同的操作系统上虽然略有差别,但是从整体架构上来看,MongoDB在不同的平台上是一样的,如数据逻辑结构和数据 ...

  9. 淘宝IP地址库API地址

    淘宝IP地址库:http://ip.taobao.com/instructions.php   接口说明 1. 请求接口(GET): http://ip.taobao.com/service/getI ...

  10. ASP.NET:插件化机制

    概述 nopCommerce的插件机制的核心是使用BuildManager.AddReferencedAssembly将使用Assembly.Load加载的插件程序集添加到应用程序域的引用中.具体实现 ...