首页 > 代码库 > 虚拟内存介绍

虚拟内存介绍

虚拟内存的性能监测包括以下步骤:
* 当系统利用内存缓存超过磁盘缓存,系统反应速度更快
* 除在有大量持续的交换空间和磁盘读入动作情况下外,空闲内存空间很少说明cache得到了有效的利用
* 如果系统报告有持续的交换空间使用,说明内存不足


虚拟内存是使用磁盘作为RAM的扩充使得可用内存的有效大小得到相应增加。内核会将当前内存中未被使用的块的内容写入硬盘以此来腾出内存空间。当上面的内容再次需要被用到时,它们将被重新读入内存。这些对用户完全透明;在linux下运行的程序只会看到有大量内存空间可用而不会去管它们的一部分时不时的从硬盘读取。当然,硬盘的读写操作速度比内存慢上千倍,所以这个程序的运行速度也不会很快。这个被用作虚拟内存的硬盘空间呗称作交换空间(swap space)。

虚拟内存页
虚拟内存被分成页,在X86架构下的每个虚拟内存页大小为4KB,当内核由内存向磁盘读写数据时,是以页为单位。内核会把内存页写入swap空间和文件系统。

内核内存分页
内存分页是一个常见的动作,不能和内存交换相混淆。内存分页是在正常间隔下同步内存中信息至磁盘的过程。随着时间的增长,应用会不断耗尽内存,有时候内核必须扫描内存并回收被分配给其他应用的空闲页面。
页帧回收算法(PFRA)
    PFRA负责回收内存。PFRA根据页类型来判断是否被回收,内存页有以下类型:
* 不可被回收——locked,kernel,reserved 被锁、内核、保留页
* 可交换——无名内存页
* 可同步——被磁盘同步的页面
* 可丢弃——静态页,废弃页
除了不可被回收类型外其他均可被PFRA回收。PFRA具有两个主要功能,一个是kswapd内核进程,一个是“Low On Memory Reclaiming”功能。
 
kswapd
    kswapd守护进程负责确保内存保持可用空闲空间。它监测内核中的pages_high和pages_low标记,如果空闲内存空间值小于pages_low值,kswwapd进程开始扫描并尝试每次回收32个页面,如此重复直至空闲内存空间大于pages_high值。
kswapd进程履行以下操作:
* 假如页面未改变,它将该页面放入free list。
* 假如页面发生改变且被文件系统回写,它将页面内容写入磁盘。
* 假如页面发生改变且未被文件系统回写(无名页),它将页面内容写入swap设备。
 
pdflush内核分页
    pdflush守护进程负责同步所有与文件系统相关的页面至磁盘,换句话说,就是当一个文件在内存中发生改变,pdflush守护进程就将其回写进磁盘。
当内存中的脏页面数量超过10%时pdflush守护进程开始回写,这个动作与内核的vm.dirty_background_ratio参数值有关。
# sysctl -n vm.dirty_background_ratio
# 10
 
多数情况下pdflush守护进程与PFRA之间是相互独立的。除了常规的回收动作之外,当内核调用LMR算法时,LMR将强制pdflush进行脏页面回收。

案例分析:大规模写入I/O
    vmstat命令除了报告CPU的情况外还能查看虚拟内存的使用情况,vmstat输出的以下区域与虚拟内存有关:
区域
描述
swapd
当前使用的虚拟内存KB数
free
当前空闲的物理内存KB数
buff
供read()和write()使用的物理内存缓冲大小
cache
映射到进程地址空间的物理内存数
so
swap out 从内存到swap写入的大小
si
swap in 从swap到内存写入的大小
bo
block out 从内存写入磁盘的大小
bi
block in 从磁盘写入内存你的大小
 
以下信息显示一个I/O限制型应用运行时的状态:
# vmstat 3 
 procs           memory              swap          io     system         cpu 
 r  b   swpd   free   buff  cache   si   so    bi    bo   in    cs us sy id wa 
 3  2 809192 261556  79760  886880  416    0  8244   751  426   863 17  3  6 75 
 0  3 809188 194916  79820  952900  307    0 21745  1005 1189  2590 34  6 12 48 
 0  3 809188 162212  79840  988920   95    0 12107     0 1801  2633  2  2  3 94 
 1  3 809268  88756  79924 1061424  260   28 18377   113 1142  1694  3  5  3 88 
 1  2 826284  17608  71240 1144180  100 6140 25839 16380 1528  1179 19  9 12 61 
 2  1 854780  17688  34140 1208980    1 9535 25557 30967 1764  2238 43 13 16 28 
 0  8 867528  17588  32332 1226392   31 4384 16524 27808 1490  1634 41 10  7 43 
 4  2 877372  17596  32372 1227532  213 3281 10912  3337  678   932 33  7  3 57 
 1  2 885980  17800  32408 1239160  204 2892 12347 12681 1033   982 40 12  2 46 
 5  2 900472  17980  32440 1253884   24 4851 17521  4856  934  1730 48 12 13 26 
 1  1 904404  17620  32492 1258928   15 1316  7647 15804  919   978 49  9 17 25 
 4  1 911192  17944  32540 1266724   37 2263 12907  3547  834  1421 47 14 20 20 
 1  1 919292  17876  31824 1275832    1 2745 16327  2747  617  1421 52 11 23 14 
 5  0 925216  17812  25008 1289320   12 1975 12760  3181  772  1254 50 10 21 19 
 0  5 932860  17736  21760 1300280    8 2556 15469  3873  825  1258 49 13 24 15 
通过以上数据可得出以下结果:
* 大量的数据从磁盘读入内存(bi),因cache值在不断增长
* 尽管数据正不断消耗内存,空闲空间仍保持在17M左右
* buff值正不断减少,说明kswapd正不断回收内存
* swpd值不断增大,说明kswapd正将脏页面内容写入交换空间(so)

虚拟内存介绍