Dynamic Memory Allocate(动态内存分配)

来源:互联网 发布:linux基础面试题 编辑:程序博客网 时间:2024/06/05 17:03

  • 介绍
  • 空闲链表
    • implicit list
    • explicit list
    • segregated list
  • Garbage Collection

刚刚写完malloc的小伙伴估计现在还心有余悸~ 不过写完以后在看书,你会发现书上的东西很简单。

转载请注明出处:http://blog.csdn.net/c602273091/article/details/53576494

介绍

动态内存分配:在程序运行时给相应变量分配内存。因为在很多时候我们只有在运行的时候才知道内存,提前分配要么就会太大,浪费了空间;要么就是太小,信息存放不下。动态内存是存在于堆空间上的。

这里写图片描述

动态内存分配器分为显式和隐式,并且在管理的时候把内存分成固定的块。显示的如malloc,new,需要自己申请和释放。隐式的如java中的垃圾回收。

在内存中,动态内存分配区域如下:
这里写图片描述

在进行malloc内存分配的时候,内部(分配给一个比payload更大的区域存放所需数据,一般是为了满足对齐要求,保留该块的一个数据结构)和外部碎片(本来可以满足请求,但是因为不连续)会降低utilization。

对于空闲链表的维护,可以使用implicit list, explicit list, segregated list, balance tree(red black tree)进行记录。下面就介绍这些链表。

空闲链表

implicit list

隐式链表就是说它没有显式地使用指针,但是可以向链表一样找到下一个节点。这个结构就是有一个头部,头部说明这个块的大小以及是否已经分配。接着是payload,然后是对齐的pending。当然这里没有画出footer,用于合并。
这里写图片描述

下面就是一个例子:
这里写图片描述

寻找空闲块的位置:块的释放和分配的过程中,设计选取块的位置。一般来说就是最先适配、最近适配、最优适配。最优适配节约空间,但是速度比较慢,在做malloc的时候不适用。使用最近适配,一般会比最先适配快,但是utilization降低了。

块的分割:在我们分配一个块的时候,如果剩余块比最小块更大,那么就可以把剩余块加入到空闲链表里面。

块的合并:当一个块被释放的时候,它会查找前后两个块是否空闲,然后合并。找到后面的块很容易,但是前面的块却找不到。所以这里加入了footer,进行合并。当然,这里说的合并是快速合并,不是推迟合并。推迟合并的话,就是扫描整个链表,看是否需要合并。推迟合并就不需要footer了。这里的footer就是大家熟悉的边界标记。

这里写图片描述

explicit list

在隐式链表上提取出来的,因为隐式链表太慢,而且需要了解到的是只有空闲链表才需要记录,已经分配的,不需要记录。那么显示链表就被提出了。

所以给空闲块增加了前驱和后驱,形成双向链表指向前后的空闲块。有了双向链表,增加,删除,修改一个节点就变得非常轻松。
这里写图片描述

在插入新节点的时候,可以用LIFO和FIFO。它们的优缺点如下图:我发现用FIFO写malloc比LIFO速度会更慢一些,但是utilization会更大。因为LIFO一般都是以最大的heap的头那块区域接近。
这里写图片描述

它和隐式链表对比,当然是速度更快,但是内部碎片很可能更大。
这里写图片描述

segregated list

分离空闲链表就是把空闲块根据大小的不同,分配到了不同的地方。

分离的空闲链表的整个数据结构可以和显示链表一样,就是多声明几个指针用于存储不同大小的空闲块。

这里写图片描述

平衡树在书上没有讲了,平衡树也就是把空闲块插入到平衡树里面,从找适配块的速度,空间利用率方面都可以大大提高。

Garbage Collection

内存管理者可以知道一个存的东西是不是指针。

一些经典的垃圾回收算法:
这里写图片描述

这里写图片描述
把内存看成是有向图,那么每个块就是一个节点,每个指针就是边。如果没有在这个有向图的范围内的内存,都可以看成垃圾。

这里写图片描述
当不在范围内的块就被标记,然后就被清理。

与内存有关的错误:
这里写图片描述

看懂下面这幅图,说明你懂指针了。
这里写图片描述

下面是我们对指针使用比较容易犯的错误。
这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

解决办法:
这里写图片描述

当然,了解动态内存最好的办法就是实现它。开始做你的malloc吧~

PS: the ppt slide is cut from CMU 18-600 Click Here

0 0