这里的讲到的"内存"包括物理内存和虚拟内存,虚拟内存(Virtual Memory)把计算机的内存空间扩展到硬盘,物理内存(RAM)和硬盘的一部分空间(SWAP)组合在一起作为虚拟内存为计算机提供了一个连贯的虚拟内存空间,好处是我们拥有的内存 "变多了",可以运行更多、更大的程序,坏处是把部分硬盘当内存用整体性能受到影响,硬盘读写速度要比内存慢几个数量级,并且 RAM 和 SWAP 之间的交换增加了系统的负担。
在电脑中,所有程序都是在内存中运行的,当运行程序所需内存不足时,内存管理就会把一些不活跃的页给转移到虚拟内存中。
虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存。而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。
在不同的系统中,都应用了虚拟内存技术。在windows中,称之为"虚拟内存",在linux中,称之为"交换空间"。
Linux 内核读写虚拟内存是以 "页" 为单位操作的,在x86系统中,每个页大小是 4KB。把内存转移到硬盘交换空间(SWAP)和从交换空间读取到内存的时候都是按页来读写的。内存和 SWAP 的这种交换过程称为页面交换。
在程序运行中,由于内核读取高速缓存内数据的速度要远远高于读取硬盘内的数据的速度,所以将会将一些关键数据保存到高速缓存中,当进程更改了高速缓存内的以页为单位的数据时,该页就被称之为"脏页"。内核将会在合适的时间把脏页的数据写到磁盘中去,以保持高速缓存中的数据和磁盘中的数据是一致的。
这里介绍内核管理内存的两个关键进程kswapd和pdflush:
kswapd
作用是用于管理内存
kswapd进程用来检查pages_hight和pages_low两个阀值,当系统可用内存低于pages_low时,便会唤醒kswapd守护进程,kswapd将开始扫描并试图释放页面,并且重复这一过程直至可用内存大于pages_hight为止。
kswapd扫描时会检查3件事:
1、如果页面没有没有被修改,这将页面放到可用内存列表里;
2、如果页面被文件系统修改了,将把页面内容写入磁盘;
3、如果页面被修改了,不过不是被文件系统修改,这将页面写入到交换空间。
pdflush
作用是用于同步文件相关的内存页面,把内存页面及时同步到硬盘上。
比如打开一个文件,文件被导入到内存里,对文件做了修改后并保存后,内核并不马上保存文件到硬盘,由 pdflush 决定什么时候把相应页面写入硬盘,这由一个内核参数 vm.dirty_background_ratio 来控制。
pdflush进程一般会被以下几种情况唤醒以回写脏页:
1、定时机制:
定时机制可定时唤醒pdflush内核进程,来回些脏页。可通过命令:
cat /proc/sys/vm/dirty_writeback_centisecs
来查看定时周期,其单位为"1/100"秒。
2、内存不足时:
此时并不会将所有脏页写入到磁盘,而时每次大概写入1024个页面,知道空闲内存满足需求为止。
3、当写操作时发现脏页超过一定比例
当脏页所占系统内存比例超过"/proc/sys/vm/dirty_background_ratio"的时候,将会唤醒pdflush进程回写脏页,知道比例低于设定值。
4、用户调用sync系统调用
系统会唤醒pdflush进程知道所有脏页全部写入磁盘为止。
有时候,通过top命令查看进程时会发现kswapd进程占用了大量的CPU资源,这个问题容易引起系统宕机,这是由于系统发现内存资源不足而唤醒kswapd进程以释放内存资源引起的,这时候只需要优化系统,释放占用太多内存的进程就可以了。