首页 > 代码库 > Linux内存管理机制

Linux内存管理机制

 

 

一、首先大概了解一下计算机CPUCache、内存、硬盘之间的关系及区别。

 

1、  CPU也称为中央处理器(CPU,Central Processing Unit)是一块超大规模的集成电路,

是一台计算机的运算核心(Core)和控制核心( Control Unit)。它的功能主要是解释计算机指令以及处理计算机软件中的数据。中央处理器主要由三核心部件组成,运算器、控制器和总线(BUS),运算器又主要由算术逻辑单元(ALU)和寄存器(RS)组成。

 

2、Cache即高速缓冲存储器,是位于CPU与主内存间的一种容量较小但速度很高的存储器。由于CPU的速度远高于主内存,CPU直接从内存中存取数据要等待一定时间周期,Cache中保存着CPU刚用过或循环使用的一部分数据,当CPU再次使用该部分数据时可从Cache中直接调用,这样就减少了CPU的等待时间,提高了系统的效率。Cache又分为一级Cache(L1 Cache)和二级Cache(L2 Cache),L1 Cache集成在CPU内部,L2 Cache早期一般是焊在主板上,现在也都集成在CPU内部,常见的容量有256KB或512KB L2 Cache。

 

3、内存是计算机中重要的部件之一,它是与CPU进行沟通的桥梁。计算机中所有程序的运行都是在内存中进行的,因此内存的性能对计算机的影响非常大。内存(Memory)也被称为内存储器,其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。内存包含的范围非常广,一般分为只读存储器(ROM)、随机存储器(RAM)和高速缓存存储器(cache)。

 

4、硬盘是电脑主要的存储媒介之一,由一个或者多个铝制或者玻璃制的碟片组成。硬盘有固态硬盘(SSD 盘,新式硬盘)、机械硬盘(HDD 传统硬盘)、混合硬盘(HHD 一块基于传统机械硬盘诞生出来的新硬盘)。

 

补充说明:

虚拟内存是计算机系统内存管理的一种技术,它是从硬盘上划分出一块空间来充当虚拟内存使用。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。目前,大多数操作系统都使用了虚拟内存,如Windows家族的“虚拟内存”;Linux的“交换空间”等。

 

 

计算机存储体系如下所示:

技术分享

 

大概理解:

  计算机硬盘存储一个文件A,假如用户去执行这个文件A,首先内存会从硬盘调取文件A的相关信息存入到内存中,内存去访问硬盘这个过程需要等待(跑车速度),当CPU去访问内存也需要等待(飞机速度),相对来说CPU <--- >内存<--- >硬盘这个过程是速度是挺快的。如果A文件放入到Cache,CPU直接去调取Cache(火箭速度),就等同于CPU不用再去访问内存,直接就访问Cache, 过程CPU<--- > 缓存,但Cache容量是非常小的,基本是存放一些经常被访问的文件,也受到了限制。

 

 

 

 

 

二、浅谈Linux系统内存管理机制

 

疑问:经常遇到一些刚接触Linux的新手会问Linux系统也没有运行太多的程序,但内存占用怎么那么多?使用top命令或都free命令都能看见如下所示:

技术分享

 

技术分享

 

 

解答:

  在Linux中经常发现空闲内存很少,似乎所有的内存都被系统占用了,表面感觉是内存不够用了,其实不然。这是Linux内存管理的一个优秀特性,在这方 面,区别于Windows的内存管理。主要特点是,无论物理内存有多大,Linux 都将其充份利用,将一些程序调用过的硬盘数据读入内存,利用内存读写的高速特性来提高Linux系统的数据访问性能。而Windows是只在需要内存时, 才为应用程序分配内存,并不能充分利用大容量的内存空间。换句话说,每增加一些物理内存,Linux都将能充分利用起来,发挥了硬件投资带来的好处,而 Windows只将其做为摆设,即使增加8GB甚至更大。

  Linux的这一特性,主要是利用空闲的物理内存,划分出一部份空间,做为cache、buffers ,以此提高数据访问性能。

  页高速缓存(cache)是Linux内核实现的一种主要磁盘缓存。它主要用来减少对磁盘的I/O操作。具体地讲,是通过把磁盘中的数据缓存到物理内存中,把对磁盘的访问变为对物理 内存的访问。

  磁盘高速缓存的价值在于两个方面:第一,访问磁盘的速度要远远低于访问内存的速度,因此,从内存访问数据比从磁盘访问速度更快。第二,数据一旦被访 问,就很有可能在短期内再次被访问到

 

标注:CPU Cache(CPU高速缓存)和linux系统的Memory Cache(内存缓存)在系统里指的不是同一个缓存,Linux系统通过free命令查看到的cache指的是Memory Cache(内存缓存)。是Linux系统引入内存机制的cache机制。

 

 

下面来了解下Linux内存管理机制:

1、物理内存和虚拟内存

  我们知道,直接从物理内存读写数据要比从硬盘读写数据要快的多,因此,我们希望所有数据的读取和写入都在内存完成,而内存是有限的,这样就引出了物理内存与虚拟内存的概念。

  物理内存就是系统硬件提供的内存大小,是真正的内存,相对于物理内存,在linux下还有一个虚拟内存的概念,虚拟内存就是为了满足物理内存的不足而提出的策略,它是利用磁盘空间虚拟出的一块逻辑内存,用作虚拟内存的磁盘空间被称为交换空间(Swap Space)。

  作为物理内存的扩展,linux会在物理内存不足时,使用交换分区的虚拟内存,更详细的说,就是内核会将暂时不用的内存块信息写到交换空间,这样以来,物理内存得到了释放,这块内存就可以用于其它目的,当需要用到原始的内容时,这些信息会被重新从交换空间读入物理内存。

  Linux的内存管理采取的是分页存取机制,为了保证物理内存能得到充分的利用,内核会在适当的时候将物理内存中不经常使用的数据块自动交换到虚拟内存中,而将经常使用的信息保留到物理内存。

 

要深入了解linux内存运行机制,需要知道下面提到的几个方面:

(1)、Linux系统会不时的进行页面交换操作,以保持尽可能多的空闲物理内存,即使并没有什么事情需要内存,Linux也会交换出暂时不用的内存页面。这可以避免等待交换所需的时间。

(2)、Linux 进行页面交换是有条件的,不是所有页面在不用时都交换到虚拟内存,linux内核根据”最近最经常使用“算法,仅仅将一些不经常使用的页面文件交换到虚拟 内存,有时我们会看到这么一个现象:linux物理内存还有很多,但是交换空间也使用了很多。其实,这并不奇怪,例如,一个占用很大内存的进程运行时,需 要耗费很多内存资源,此时就会有一些不常用页面文件被交换到虚拟内存中,但后来这个占用很多内存资源的进程结束并释放了很多内存时,刚才被交换出去的页面 文件并不会自动的交换进物理内存,除非有这个必要,那么此刻系统物理内存就会空闲很多,同时交换空间也在被使用,就出现了刚才所说的现象了。关于这点,不 用担心什么,只要知道是怎么一回事就可以了。

(3)、交换空间的页面在使用时会首先被交换到物理内存,如果此时没有足够的物理内存来容纳这些页 面,它们又会被马上交换出去,如此以来,虚拟内存中可能没有足够空间来存储这些交换页面,最终会导致linux出现假死机、服务异常等问题,linux虽 然可以在一段时间内自行恢复,但是恢复后的系统已经基本不可用了。

因此,合理规划和设计Linux内存的使用,是非常重要的.

 

 

2、 Linux 内存的监控

  作为一名Linux系统管理员,监控内存的使用状态是非常重要的,通过监控有助于了解内存的使用状态,比如内存占用是否正常,内存是否紧缺等等,监控内存最常使用的命令有free、top等,下面是某个系统free的输出:

技术分享

 

每个选项的含义:

第一行Mem:

total:表示物理内存总量。

used:表示总计分配给缓存(包含buffers 与cache )使用的数量,但其中可能部分缓存并未实际使用。

free:未被分配的内存。

shared:共享内存,一般系统不会用到,这里不讨论。

buffers:系统分配但未被使用的buffers 数量。

cached:系统分配但未被使用的cache 数量。

 

第二行-/+ buffers/cache:

used:实际使用的buffers 与cache 总量,也是实际使用的内存总量。

free:未被使用的buffers 与cache 和未被分配的内存之和,这就是系统当前实际可用内存。

 

第三行Swap:

total:交换空间总量。

used:已经使用的交换空间。

Free:未被使用的交换空间。

 

系统实际内存计算:(第二行-/+ buffers/cache)

(Linux系统已经使用的实际内存)used = (第一行)used  减去  (第一行)buffers 减去 (第一行)cache

(Linux系统未被使用的实际内存)free = (第一行)free  加上  (第一行)buffers 加上 (第一行)cache

 

free命令输出的内存状态,可以通过两个角度来查看:一个是从内核的角度来看,一个是从应用层的角度来看的:

 

从内核的角度来查看内存的状态

就是内核目前可以直接分配到,不需要额外的操作,即为上面free命令输出中第二行Mem项的值,可以看出,此系统物理内存总量有32113M,已经使用的内存只有3 53M,我们来做一个这样的计算:

32113 – 31759 = 353

其实就是总的物理内存减去已经使用的物理内存得到的就是空闲的物理内存大小,注意这里的可用内存值353M并不包含处于buffers和cached状态的内存大小。

如果你认为这个系统空闲内存太小,那你就错了,实际上,内核完全控制着内存的使用情况,Linux会在需要内存的时候,或在系统运行逐步推进时,将buffers和cached状态的内存变为free状态的内存,以供系统使用。

 

从应用层的角度来看系统内存的使用状态

也就是Linux上运行的应用程序可以使用的内存大小,即free命令第三行 -/+ buffers/cached 的输出,可以看到,此系统已经使用的内存才7536M,而空闲的内存达到24576M,继续做这样一个计算:

353+(7+24215)=24576

通过这个等式可知,应用程序可用的物理内存值是Mem项的free值加上buffers和cached值之和,也就是说,这个free值是包括buffers和cached项大小的,对于应用程序来说,buffers/cached占有的内存是可用的,因为buffers/cached是为了提高文件读取的性能,当应用程序需要用到内存的时候,buffers/cached会很快地被回收,以供应用程序使用。

 

buffers与cached的异同

 

缓存(cached是把读取过的数据保存起来,重新读取时若命中(找到需要的数据)就不要去读硬盘了,若没有命中就读硬盘。其中的数据会根据读取频率进行组织,把最频繁读取的内容放在最容易找到的位置,把不再读的内容不断往后排,直至从中删除

 

缓冲(buffers是根据磁盘的读写设计的,把分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,从而提高系统性能。

 

  在Linux 操作系统中,当应用程序需要读取文件中的数据时,操作系统先分配一些内存,将数据从磁盘读入到这些内存中,然后再将数据分发给应用程序;当需要往文件中写 数据时,操作系统先分配内存接收用户数据,然后再将数据从内存写到磁盘上。然而,如果有大量数据需要从磁盘读取到内存或者由内存写入磁盘时,系统的读写性 能就变得非常低下,因为无论是从磁盘读数据,还是写数据到磁盘,都是一个很消耗时间和资源的过程,在这种情况下,Linux引入了buffers和 cached机制。

  cached是cpu与内存间的,buffer是内存与磁盘间的,cache和buffer都是Linux内核使用物理内存调配出去的容量,都是为了解决速度不对等的问题。buffers与cached都是内存操作,用来保存系统曾经打开过的文件以及文件属性信息,这样当操作系统需要读取某些文件时,会首先在buffers 与cached内存区查找,如果找到,直接读出传送给应用程序,如果没有找到需要数据,才从磁盘读取,这就是操作系统的缓存机制,通过缓存,大大提高了操 作系统的性能。但buffers与cached缓冲的内容却是不同的。

  buffers是用来缓冲块设备做的,它只记录文件系统的元数据(metadata)以及 tracking in-flight pages,而cached是用来给文件做缓冲。更通俗一点说:buffers主要用来存放目录里面有什么内容,文件的属性以及权限等等。而cached直接用来记忆我们打开过的文件和程序。

 

Linux内存管理机制