by leezy_2000
2003-10-8 17:01
三、浅谈一下Heap
(鉴于Matt Pietrek在它的《Windows 95 系统程式设计大奥秘》对9x系统的heap做了非常详细的讲解,此处涉及的内容将仅限于Win2000)
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
Heap与Stack正好相反,你需要手动来管理每一块内存的申请和释放(在没有垃圾收集机制的情况下),而对于C/C++程序员来说,操作Heap的方式实在是太多了点。下面是几乎所有可以操作堆内存的方法的列表:
malloc/free
new/delete
GlobalAlloc/GlobalFree
LocalAlloc/LocalFree
HeapAlloc/HeapFree
其中malloc/free由运行时库提供,new/delete为C++内置的操作符。他们都使用运行时库的自己的堆。运行时库的在2000和win9x下都有自己独立的堆。这也就意味着只要你一启动进程,你将至少有两个堆,一个作为进程缺省,一个给C/C++运行时库。
GlobalAlloc/GlobalFree和LocalAlloc/LocalFree现在已失去原有的含义,统统从进程缺省堆中分配内存。
HeapAlloc/HeapFree则从指定的堆中分配内存。
单就分配内存而言(new/delete还要管构造和析构),所有这些方式最终要归结到一点2000和98下都是是HeapAlloc。所以微软才会强调GlobalAlloc/GlobalFree和LocalAlloc/LocalFree会比较慢,推荐使用HeapAlloc,但由于Global**和Local**具有较简单的使用界面,因此即使在微软所提供的源代码中他们仍被大量使用。必须指出的是HeapAlloc并不在kernel32.dll中拥有自己的实现,而是把所有调用转发到ntdll.RtlAllocateHeap。下面这张从msdn中截取的图(图2),应该有助于我们理解同堆相关的API。
堆内部的运作同SGI STL的分配器有些类似,大体上是这样,OS为每个堆维护几个链表,每个链表上存放指定大小范围的区块。当你分配内存时,操作系统根据你所提供的尺寸,先确定从那个链表中进行分配,接下来从那个链表中找到合适的块,并把其线性地址返还给你。如果你所要求的尺寸,在现存的区块中找不到,那么就新分配一块较大的内存(使用VirtualAlloc),再对他进行切割,而后向你返还某一区块的线性地址。这只是一个大致的情形,操作系统总在不停的更新自己的堆算法,以提高堆操作的速度。
堆本身的信息(包括标志位和链表头等)被存放在Heap Header中,而堆句柄正是指向Heap Header的指针,Heap Header的结构没有公开,稍后我们将试着做些分析。非常有趣的是微软一再强调只对toolhelp API有效的HeapID其实就是堆句柄。
原来是准备分析一下堆内部的一些结构的,可后来一想这么做实用价值并不是很大,所需力气却不小。因此也就没具体进行操作。但这里把实现监测堆中各种变化的小程序的实现思路公开一下,希望对大家有所帮助。这个小程序非常的简单,主要完成的任务就是枚举进程内所有的堆的变化情况。由于涉及到比较两个链表的不同,这里使用了STL的vector容器和某些算法来减少编码。同时为了使STL的内存使用不对我们要监测的对象产生干扰,我们需要建立自己的分配器,以使用我们单独创建的堆。此外还需要特别注意的一点是由于toolhelp API Heap32Next在运行过程中不允许对任何堆进行扰动(否则他总返回TRUE),导致我们只能使用vector,并预先保留足够的空间。(访问堆内部某些信息的另一种方式是使用HeapWalk API,看个人喜好了)。
程序的运行过程是这样的,先对当前进程中存在的堆进行枚举,并把结果存入一个set类型的变量heapid1,接下来创建自己的堆给分配器使用,并对进程中存在的堆再次进行枚举并把结果存入另一个set类型的变量heapid2,这样就可以调用set_difference求出我们新建堆的ID,再以后列举队内部的信息时将排除这个ID所表示的堆。接下来就可以在两点之间分别把堆内部的信息存入相应的vector,比较这两个vector,就可以得到对应于分配内存操作,堆内部的变化情况了。
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 252.75pt; HEIGHT: 258pt" type="#_x0000_t75"><img o:title="heap" src="/Develop/ArticleImages/21/21436/CSDN_Dev_Image_2003-10-81710470.gif"><font size="3"></font></shape>
(图2 from msdn by Murali R. Krishnan)
下面是一些悬而未决的问题,那位感兴趣可以自己探索。
Heap Header结构是什么样的?
堆内部对内存块的组织方式?(是链表么)
每一个小块的描述信息在那里?(如果是链表,那就应该有指针使这些小块彼此相连。)
分享到:
相关推荐
虚拟内存是现代操作系统的关键特性,这部分详细阐述了Windows的虚拟内存机制。包括页面交换、页面缓存和工作集的概念,以及如何通过这些技术在物理内存有限的情况下,提供近乎无限的地址空间。同时,探讨了分页文件...
本文旨在深入解析Windows内存管理机制,并通过实例讲解如何在C++中有效地分配和使用内存。 首先,我们要了解的是进程的地址空间。在32位系统中,进程地址空间被分为几个主要部分。NULL指针分区从0x0000 0000到0x...
【Windows内存管理机制】 Windows内存管理机制是操作系统中至关重要的组成部分,它负责为应用程序分配、管理和回收内存资源。本文将详细解析Windows系统如何管理和利用内存,特别是针对32位和64位系统的区别。 1. ...
《深入解析Windows操作系统》第六版是一本权威且深入的技术书籍,专注于揭示Windows 7和Windows Server 2008 R2操作系统的内核层面的工作原理。本书由David A. Solomon和Mark Russinovich两位专家撰写,他们对于...
总之,获取Windows内存信息在Qt中可以通过多种方式实现,如使用`QProcess`执行`wmic`命令、非公开的`QMemoryInfo`类或者直接调用Windows API。选择哪种方法取决于项目需求和对稳定性的考虑。无论哪种方式,都要注意...
以下是对Windows内存管理的深入解析: 一、内存分配 1. **基本概念**:内存是计算机用来存储数据和程序的地方,分为物理内存和虚拟内存。物理内存即RAM(随机存取存储器),是硬件层面的内存;虚拟内存则是硬盘上...
内存编程是计算机科学中的核心概念,特别是在开发操作系统和低...在Windows环境中,内存管理不仅涉及程序内部,还包括与操作系统交互的部分,如虚拟内存管理和内存保护机制,这些内容对于深入学习Windows编程至关重要。
深入解析WINDOWS操作系统(第4版) ISBN:9787121039690 本书是著名的操作系统内核专家Mark Russinovich和David Solomon撰写的Windows操作系统原理的最新版著作,全面和深入地阐述了Windows操作系统的整体结构以及...
《深入解析Windows操作系统》是针对Windows Internals第四版的一份详细知识解读,旨在为读者揭示Windows操作系统的内部工作机制。这本书由权威专家编写,是IT专业人士深入理解Windows内核、系统服务、安全机制以及...
《深入解析Windows操作系统 第5版》是一本专为IT专业人士和高级用户编写的经典书籍,旨在揭示Windows操作系统的深层机制和工作原理。该书详细介绍了Windows操作系统的核心组件、设计架构以及内部运作流程,帮助读者...
《深入解析:Windows操作系统》(第4版)全书内容丰富、信息全面,主要包括的Windows操作系统深度知识有:理解Windows的关键机制,包括系统服务分发和调度机制、启动和停机,以及注册表;挖掘Windows的安全模型,包括...
- **内存管理子系统**:详细解释了Windows如何管理和分配内存资源,包括物理内存管理、虚拟内存管理等。 - **缓存管理器**:分析了Windows如何使用缓存来提高数据访问效率。 - **文件系统**:讨论了Windows支持的...
在实际操作中,内存解析工具是必不可少的,如windbg(Windows平台)、gdb(通用调试器)或者Volatility(内存取证框架)。这些工具可以帮助我们查看内存内容,跟踪指针,查找特定数据结构,甚至重建程序的执行流程。...
《深入解析Windows操作系统》这本书籍可谓Windows操作系统的内核级指南,它不仅详细地解读了Windows操作系统的工作原理和系统架构,还深入地剖析了其底层机制。这本书籍以其英文版的形式,为国际上的IT专业人士,...
这部分内容将介绍Windows如何分配和管理虚拟内存和物理内存,包括页表结构、分页机制、地址转换过程等。它还会探讨内存管理的一些高级特性,比如内存共享、大页面支持等。 - 更多内容:除了上述几个主题外,作为一...
##### 3.3 DLL机制解析 动态链接库(DLL)是Windows系统中一种常见的共享库形式,多个应用程序可以同时访问同一DLL中的函数,从而节省内存和提高效率。DLL机制的关键在于: - **加载和卸载**:通过`LoadLibrary`...
#### 三、Windows内存映射机制的关键API 1. **CreateFileMapping**:用于创建一个内存映射文件对象。这个函数接收一个已打开文件的句柄作为参数,并返回一个内存映射文件对象的句柄。 - `HANDLE CreateFileMapping...
2. **数据解析**:获得内存镜像后,分析人员使用各种工具和技术解析内存中的数据结构,如进程列表、网络栈信息、注册表项等。 3. **数据恢复**:即使某些数据在内存中被删除或覆盖,高级分析技术仍有可能恢复这些...
5. 观察Windows内存管理机制。本书解释了Windows如何管理虚拟内存和物理内存,这对于优化内存使用、处理内存泄漏和提高系统整体性能至关重要。 6. 理解NTFS文件系统的操作和格式。Windows系统大多使用NTFS文件系统...