Windows内存机制解析(二)

原创 2003年10月09日 17:09:00

                           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" />

HeapStack正好相反,你需要手动来管理每一块内存的申请和释放(在没有垃圾收集机制的情况下),而对于C/C++程序员来说,操作Heap的方式实在是太多了点。下面是几乎所有可以操作堆内存的方法的列表:

malloc/free

new/delete

GlobalAlloc/GlobalFree

LocalAlloc/LocalFree

HeapAlloc/HeapFree

 

其中malloc/free由运行时库提供,new/deleteC++内置的操作符。他们都使用运行时库的自己的堆。运行时库的在2000win9x下都有自己独立的堆。这也就意味着只要你一启动进程,你将至少有两个堆,一个作为进程缺省,一个给C/C++运行时库。

 

GlobalAlloc/GlobalFreeLocalAlloc/LocalFree现在已失去原有的含义,统统从进程缺省堆中分配内存。

 

HeapAlloc/HeapFree则从指定的堆中分配内存。

 

单就分配内存而言(new/delete还要管构造和析构),所有这些方式最终要归结到一点200098下都是是HeapAlloc。所以微软才会强调GlobalAlloc/GlobalFreeLocalAlloc/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其实就是堆句柄。

 

原来是准备分析一下堆内部的一些结构的,可后来一想这么做实用价值并不是很大,所需力气却不小。因此也就没具体进行操作。但这里把实现监测堆中各种变化的小程序的实现思路公开一下,希望对大家有所帮助。这个小程序非常的简单,主要完成的任务就是枚举进程内所有的堆的变化情况。由于涉及到比较两个链表的不同,这里使用了STLvector容器和某些算法来减少编码。同时为了使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" />CSDN_Dev_Image_2003-10-81710470.gif

(2 from msdn by Murali R. Krishnan)

 

下面是一些悬而未决的问题,那位感兴趣可以自己探索。

 

Heap Header结构是什么样的?

 

堆内部对内存块的组织方式?(是链表么)

 

每一个小块的描述信息在那里?(如果是链表,那就应该有指针使这些小块彼此相连。)

深入理解Linux内存管理机制

深入理解Linux内存管理机制(一) 浏览次数:595次2012年08月03日淘宝核心系统团队博客字号: 大 中 小 分享到:QQ空间新浪微博腾讯微博人人网豆瓣网开心网更多1 深...
  • haiross
  • haiross
  • 2014年08月29日 10:45
  • 1984

win10系统调用架构分析

1.  操作系统模型 大多数操作系统中,都会把应用程序和内核代码分离运行在不同的模式下。内核模式访问系统数据和硬件,应用程序运行在没有特权的模式下(用户模式),只能使用有限的API,且不能直接访...
  • liuyez123
  • liuyez123
  • 2016年03月27日 16:25
  • 4260

Oracle内存详解之一 整体架构

Oracle的内存配置与Oracle性能息息相关。关于内存的配置,是最影响Oracle性能的配置。内存还直接影响到其他两个重要资源的消耗:CPU和IO.   先看Oracle内存存储的主要内容是什...
  • u011364306
  • u011364306
  • 2015年12月03日 16:33
  • 1153

全面介绍Windows内存管理机制及C++内存分配实例

  • 2011年07月19日 06:50
  • 829KB
  • 下载

Windows内存管理机制及C++内存分配

  • 2011年06月21日 10:38
  • 103KB
  • 下载

全面介绍Windows内存管理机制及C++内存分配实例

  • 2009年05月21日 10:42
  • 129KB
  • 下载

全面介绍Windows内存管理机制及C++内存分配实例.pdf

  • 2012年02月15日 10:04
  • 862KB
  • 下载

Windows内存管理机制

Windows内存管理机制 目录(?)[+] 一进程空间 二内存状态查询三虚拟内存四内存映射文件五堆 六堆栈 (一):进程空间 在编程中,很多Windows或...
  • A0905
  • A0905
  • 2015年08月13日 20:28
  • 273

windows7内存管理机制

读过了“Sevir”的《windows vista wow》之后,受益匪浅。虽说不是成为了一个“专家”,但也对从vista开始引进的新的内存管理机制Superfetch有了一定的了解。发现了很多人一开...
  • wwwkingdee
  • wwwkingdee
  • 2011年04月13日 10:55
  • 1631

Windows内存管理机制

原文网址: http://www.2cto.com/os/201107/95812.html 本文主要内容: 1.基本概念:物理内存、虚拟内存;物理地址、虚拟地址、逻辑地址;页目录,...
  • qq125537082
  • qq125537082
  • 2013年04月09日 23:39
  • 576
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Windows内存机制解析(二)
举报原因:
原因补充:

(最多只允许输入30个字)