Linux内存管理和源码分析——概述

一、基本介绍

前面分析了不少的库的内存管理,以后仍然会继续分析一些库的内存管理。但在库的内存管理时,最终仍然会调用内核的内存管理接口。这就不禁让人有些好奇,在OS中,是如何对内存进行管理的呢?当然,这个话题如果是计算机专业的话,操作系统原理一定会把相关的虚拟内存、物理内存、页、段、栈、寄存器等等都讲的很清晰。但回过头来细琢磨,又好像没有一个实际的东西在头脑中,怎么办呢?那就不如找开源的Linux内核针对实际情况分析一下。内核的内存管理是如此之复杂,所以准备用较长的一段时间,仔细认真的结合源码和资料,把相关内核中对内存管理的代码和算法、流程等认真分析一遍。
其实在Linux内核中,如果从现在的角度来看,算法是最重要的。但是从内存管理的整体来看,内存管理体系的设计又是非常重要的,而算法只是其中实现的一个具体的环节。这也是学习计算机体系设计的一个重要原因,算法就是为实现这个体系设计服务的。如果回头看计算机发展的历史,特别是内存管理从无到有的发展过程,更会清晰的看到这个思路。

二、Linux内存管理的演进

Linux内存管理的历史其实和OS内存管理的历史没有什么太大不同,如果说不同,可能是缺失了前一段的一些历史。这个很正常,毕竟Linux是一个后来的操作系统。现在就简单的回望一下整个计算体系中内存管理的历史过程:
1、计算机的原始时代
在这个时代,没有操作系统,没有内存管理,没有我们常说的线程进程,只有一些电子管来模拟完成这些动作。
2、初级管理系统时代
在这个时代基本有了集成电路,有了一些近似OS的管理系统,比如批处理系统,可以对道程、内存和CPU进行管理,其实更主要的还是对CPU管理。对内存的管理也仅限于对物理内存的直接管理。在后期增加了一些内存的抽象管理,但仍然仅仅是抽象出一些地址空间,增加了一些内存的保护机制。
3、早期操作系统时代
在这个时代,出现包括UNIX的早期萌芽Multics,OS开始变得越来越复杂,对各种资源的需求越来越竞争激烈,此时就出现了真正的操作系统,以UNIX为代表,此时,虚拟内存正式进入计算机的世界,物理内存被OS隔离了。但此时仍然是以大型机、小型机这些巨无霸的存在上运行为主。
4、个人电脑和服务器时代
个人电脑的出现,才从真正意义上把操作系统普及到了千家万户,在这之前,操作系统这个东西更像一个专业术语,仅停留在实验室和一些大学中。而随着微软不断的强化Windows,一些技术人员开始反对它的垄断,就出现了Linux。在这个时代里,对内存的管理才算是真正的向普通开发和技术人员普及起来。此时Unix也不断发展,出现了不同的版本。DOS系统和Linux系统都是在这个时期出现的。甚至后来的终端OS如IOS和安卓等也都可以划到这个范畴里来。
虚拟内存的引入,各种对内存管理的算法、机制都不断的被应用研究出来,包括常见的段、页等开始为大多数技术人员所了解,学习。
5、分布式OS时代
现在计算机的发展走到了一个瓶颈,纵向挖掘计算机的性能基本已经无法实现,那么把多个计算机组合起来形成更强大的网络体系的并行计算机群就成为了一种必然,而为了管理这些计算机,就必须要有一个OS。并行时代的OS,目前还没有一个能强大到如Windows和Linux那样的操作系统,或者说这种OS正在快速发展中,但短期内仍然无法看到一个优秀的分布式OS的出现。在这种计算机的内存管理中,管理更倾向于内存在分布式系统中的资源调配和动态内存的控制平衡。

三、目前主流的算法

内存的分配管理按内存是否连续划分为两大类,即连续内存管理和非连续内存管理,目前主流的操作系统主要是非连续内存的管理,但对于一些小内存和嵌入式系统管理中,连续内存管理也比较常见。而按照应用分区划分可以划分为固定分区内存管理和动态分区内存管理。
1、内存管理的算法
目前比较主流的内存管理的算法主要有以下几种:
a) First Fit(首次适应算法)
First Fit就是按照空闲分区的顺序从头开始查找,直到找到相适应的空闲分区终止。
b) Next Fit(循环首次适应算法)
Next Fit由First Fit算法演变而来。内存分配是循环从链表中进行查找,最初从上一次分配过的空闲分区之后开始查找,直到达到分配目的,如果到链表尾端都没有找到则跳回到头空闲分区继续查找。

c) Best Fit(最佳适应算法)
所有的空闲分区按从小到大的顺序排序,然后从中查找出最适合的空闲内存(即大小最低下限)。

d) Worst Fit(最坏适应算法)
和上面的类似,不过恰恰相反是,找出空闲分区大小的最大下限。也就是最大的分区。

e) Two LevelSegregated Fit(TLSF)
就是为了更好的适应内存分配,把链表分成两层,都用链表管理,链表划分成不同的大小单元,就类似前面分析过的内存分配中的ClassSize的大小。分配内存时,从最适应的链表内查找,这样效率更高,利用率更好。

f) Buddysystems(伙伴算法)
Segregated Fit算法的变种,在内存拆分和回收合并上效率较高。伙伴算法有BinaryBuddies,Fibonacci Buddies等很多,但简单的就是Binary Buddies,其通过双向链表管理2的幂的大小分区来控制内存的分配,空闲分区在相同类的情况下大小一致。由于需要对一些内存进行拆分,所以产生内存碎片的机率比较大。

2、页面转换算法
内存的页面的数据如何管理,也需要算法来控制,比如哪些页面OS认为需要回收或者替换出去,其相关的算法有:
a) FIFO先进先出算法
这个好理解,最先进入的内存页被换出,但这个容易导致缺页率增加.

b) LRU最近最久未用算法
通过一个链表按使用时间和次数进行排序,换出最近一定时间内的最长时间未用的页面。
b) OPT最优转换算法
这个算法就是把最久没有使用的页换出去,从概率上讲,这种缺页率最小,但也要看具体的场景。而且这种算法实践起来有难度。
d) SCR第二次机会算法
这个其实和FIFO没啥太大区别,就是增加一个标志位,来判断最近是否访问,如果访问就把它挪到链表的尾部,这样就等于是重新定义了FIFO。但在某种比较恶劣的情况下,会退化为FIFO算法。

3、内核使用的算法
Linux的初始是一个非常简陋的OS,网上有很多早期代码分析相关的文章。其中有一个大学老师的分析0.11版本的,有兴趣看,就会发现Linux当时真的很简陋。但做为开源软件的头部软件,很快就在众多Geek的支持下快速的成长起来。和Windows对比的一些明显落后的短板相继被补齐,甚至在某些场景大踏步超过Windows(比如在嵌入式和服务器)。特别是在服务器的操作系统安装上,即使Windows使出各种解数,仍然是被Linux远远抛在后面。
在多核系统中,CPU对物理内存一视同仁,这种体系结构被称为Uniform Memory Access(UMA)。如果物理内存是分布式的,由多个单元组成,CPU访问内存近快远慢(亦或本地之与全局),此类体系结构被称为Non-Uniform Memory Access(NUMA)。
Linux通过抽象内存按照不同的节点为Node,Node即为某Cpu的本地节点内存,其它CPU的远端内存。在UMA结构下, 任务系统中只存在一个内存node, 即内核把内存当成只有一个内存node节点的伪NUMA。
内存管理区(zone)主要有ZONE_DMA, ZONE_NORMAL, ZONE_HIGHMEM 三种类型,分别用来描述DMA,顺序的规则映射页和高地址不映射页面。至于其具体的部置则和具体的硬件体系有关。
Linux中内存管理的算法也是在这个过程中不断发展和变化的,主要使用的算法包括:
a) Slab分配算法
slab分配器将大小相同的内核对象放在一起,当对象被free了之后并不是直接还给伙伴系统,而是将这部分对象的页面保存下来,在下一次该类对象的内存申请时分配给新的对象。可以把其想象成一个内存的缓冲池,由于它是小的,频繁的分配会引入大量的内存碎片,所以使用缓冲池一方面可以提高分配使用的效率另外一方面可以降低内存碎片的数量。但是相应的,复杂性也有了较大的提升。

b) Buddy伙伴分配算法
Buddy 算法将所有的空闲物理页分成 10 组,每组分别包含大小 1,2,4,8,16,32,64,128,256,512 个连续物理页。每一组用链表组织起来。如果临近的两组空闲内存大小一致,则将其合并起来形成新的空闲内存,这样做可以较好的解决内存碎片的问题。这个算法稳定使用已经几十年了,在这个过程中不断的进行完善和优化。

Linux内核因为是开源的,所以除了官方版本外,其它一些公司也都进行了各种定制,相关的算法这里就不再说,它们的主要原理也不外乎是这些常用的内存分配管理手段的单独和综合、优化的应用。

四、总结

分析内核的源码,是对自己学习Linux系统这不少年来的一次系统的整理和总结。正所谓“学而不思则罔,思而不学则殆!”学习和思考本身就是一个螺旋渐进的过程,有一个否定之否定的演进。学习和思考,理论和实践,要紧密的结合起来。
在后面的系列的文章中,会结合着Linux的源码把相关的算法等说明分析,掌握理论是如何与实际代码实践结合的并分析一些细节的具体实现以及一些实现上的优化和细微的不同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值