浅谈linux内存管理


linux内存管理的两个主要特征是进程虚拟内存和内核内存分配。

      先来谈谈进程虚拟内存是什么,linux使用三级页表结构,由页目录,页中间目录,页表构成。

     页目录:一个活动的进程有一个页目录,页目录大小为一页尺寸,页目录中的每一项都指向页中间目录的一页。

     页中间目录:页中间目录可以有多个页,页中间目录的每一项指向页表中的一页。

     页表:页表也可以有多页,每个页表项指向该进程的一个虚拟页。

     虚拟内存方案的地址转换如下:

\

       为了提高读写内存的效率,linux把连续的页映射到连续的叶框中,基于这种目的,linux使用了伙伴系统内核维护一系列固定大小的叶框组一页可以包含1、2、4、8、16、32个叶框,当一页在内存中分配或者回收时,可用的组使用伙伴算法被分裂或合并。

      linux的页面置换算法是时钟算法的变种。

 

 

      内核内存分配是什么,内核内存管理物理内存页框,主要是为特定的使用分配和回收页框,而页框的拥有者可能是用户空间的进程,动态分配的内核数据,静态内核代码和高速缓存等,linux的内核内存分配使用的是基于用户虚拟内存管理的分页机制,在分页机制中使用伙伴算法可以以一页或者多页为单位分配,所以这种分配的单位最小是页,而内核中有许多小对象,这些对象的构建和回收十分频繁,如inode,如果每次构件时就向内核申请一个页,而其实实际大小可能只有几个字节,这样就非常浪费,所以linux在分配页时采用了一种slab机制,一般的页尺寸为4K,而slab就是用来处理在同一页框中分配小存储区,小于一页的块可以非配给32、64、128、256...4048字节,linux维护了一组缓存链表,每种块大小对应一个链表,块可以按照类似伙伴算法的方式进行合并,并且可以在链表间移动。

slab层主要起到了两个方面的作用:

     1. slab可以对小对象进行分配,这样就不用为每个小对象分配一个页框,节省了空间。

     2. 内核中的一些小对象创建析构很频繁,slab对这些小对象做了缓存,可以重复利用一些相同的对象,减少内存分配次数。

     slab结构如下:

\

     

     linux是通过高速缓存来管理相同大小的块或者说对象吧。每个缓存都包含了一组slab列表,主要有三种不同类型的slab组成的链表:

    slab_full:完全分配了,没有空闲的列表

    slab_partial:分配了部分块的列表

    slab_free:完全空闲的slab

    当请求内存时会先从slab_partial中寻找,如果没有就会去slab_free中去寻找,然后将这个slab放入slab_partial中。

    与传统的内存管理模式相比, slab 缓存分配器提供了很多优点。首先,内核通常依赖于对小对象的分配,它们会在系统生命周期内进行无数次分配。slab 缓存分配器通过对类似大小的对象进行缓存而提供这种功能,从而避免了常见的碎片问题。slab 分配器还支持通用对象的初始化,从而避免了为同一目而对一个对象重复进行初始化。最后,slab 分配器还可以支持硬件缓存对齐和着色,这允许不同缓存中的对象占用相同的缓存行,从而提高缓存的利用率并获得更好的性能。

     参考链接:https://www.ibm.com/developerworks/cn/linux/l-linux-slab-allocator/

相关内容

    暂无相关文章