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. VBA笔记-参考教程

    参考教程1: http://www.cnblogs.com/wuzhiblog/tag/VBA/ 1. VBA中字符换行 VBA中字符换行显示需要使用换行符来完成.下面是常用的换行符          ...

  2. No.13 selenium for python 单选框和复选框

    单选框 radio 点击图标,可以获取HTML中定位. 使用普通的ID定位就可以了 定位到指定元素,然后使用clicd选中即可 复选框 checkbox 勾选单个框,跟单选框一样,定位后点击就可以了 ...

  3. Tensorflow之训练MNIST(1)

    先说我遇到的一个坑,在下载MNIST训练数据的时候,代码报错: urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FA ...

  4. 面试题:输入两个整数 n 和 m,从数列1,2,3…….n 中 随意取几个数, 使其和等于 m

    问题: 2010年中兴面试题 编程求解: 输入两个整数 n 和 m,从数列1,2,3…….n 中 随意取几个数, 使其和等于 m ,要求将其中所有的可能组合列出来. 思路: 类似这种组合问题一般都是使 ...

  5. AngularJs(SPA)单页面SEO以及百度统计应用(上)

    只有两种人最具有吸引力,一种是无所不知的人,一种是一无所知的人 问:学生问追一个女孩总是追不上怎么办?回答:女孩不是追来的,是吸引来的,你追的过程是吸引女孩的过程,如果女孩没有看上你,再追都是没有用的 ...

  6. Linux--忘记MySQL密码的解决方法和输入mysqld_safe --skip-grant-tables &后无法进入MySQL的解决方法

    https://blog.csdn.net/qq_35389417/article/details/78910974

  7. Zookeeper学习笔记-概念介绍

    目录 概念 背景介绍 zookeeper一致性 使用建议 概念 ZooKeeper是一个开源的分布式协调服务,它为分布式应用提供了高效且可靠的分布式协调服务,提供的功能包括:配置维护.域名服务.分布式 ...

  8. 1089: [SCOI2003]严格n元树

    好久没更新了..于是节操掉尽python水过本来就水的题.. n,d=map(int, raw_input().split()) if d==0: print 1 else: f=[1] for i ...

  9. Zookeeper服务器集群的搭建与操作

    ZooKeeper 作用:Zookeeper 可以用来保证数据在zk集群之间的数据的事务性一致(原子操作). 介绍:Zookeeper 是 Google 的 Chubby一个开源的实现,是 Hadoo ...

  10. Qt Creator在Windows上的调试器安装与配置

    如果安装Qt时使用的是Visual Studio的预编译版,那么很有可能就会缺少调试器(Debugger),而使用MSVC的Qt对应的原生调试器是CDB(对应MinGW的Qt使用GDB调试器).本文介 ...