堆内存

来源:互联网 发布:php base64解码 乱码 编辑:程序博客网 时间:2024/04/29 20:20

引自http://blog.csdn.net/gaoxin1076/article/details/8078404

不同平台操作系统对内存的管理机制是不一样的。

上面这本书里面主要讲了对windows2000 - windows xp1 平台的堆管理策略。

对于基本的操作系统中堆的一些特征,这里就不再讲了。这里主要说说内存中堆的数据结构。

自己画了张图给大家看看。。。

                                      (堆的内存组织)

现代操作系统的堆数据结构一般包括堆块和堆表两类。

堆块:堆区的内存按照不同大小组织成块,以堆块为单位进行标识,而不是按照字节标识。一个堆块包括两个部分:块首和块身

块首是堆块头部的几个字节,用来标识这个堆块自身的信息,包括本块的大小、本块空闲还是占用等信息;

块身紧跟在块首后面的部分,是最终分配给用户使用的数据区。

我们在程序中很难感觉到块首的存在。但是正是由于这个块首的存在,解决了我上几天提出的为什么free的地址必须是malloc的地址 还有free的长度是确定的这两个问题。

因为这些信息全部包含在块首里面,释放的时候必须进行比对,如果比对结果失败,那么自然是无法进行free操作了.(个人猜测,求验证)


堆表:位于堆区的起始位置,用于索引堆区中堆块的重要信息。堆表的数据结构决定了整个堆区的组织方式。堆表在设计时可能会考虑采用平衡二叉树等高级数据结构用于优化查找效率。现代操作系统的堆表往往不止一种数据结构。

在windows中,占用态的堆块被使用它的程序索引,而堆表只索引所有空闲态的堆块。

重要的堆表有两种:空闲双向链表FreeList(空表) 和 快速单向链表Lookaside(快表)

空闲双向链表FreeList(空表):

堆区一开始的堆表区中有一个128项的指针数组(看到有人说把它看成队列的),被称作空表索引。该数组的每一项包含两个指针,用于表示一条空表。

free[1] 标识了所有堆中所有大小为8字节的空闲堆块,之后每个索引指示的空闲堆块递增8个字节。即:

free[2]标识了16个字节的空闲堆块。

free[k] 标识了 k * 8 个字节的空闲堆块。

指示第1项空表索引比较特殊,从图中我们也可以看到:这条双向链表链入了所有大于等于1024字节的堆块(小于512KB),堆块按照升序排列。



快速单向链表Lookaside(快表)

为什么叫做快表呢?因为速度快。。。为什么速度快呢?。。因为这类单向链表中从来不会发生堆块合并。

结构组织和空表差不多,只是每条快表最多只有4个结点,故很快就会被填满。



0 0