分类:
2011-11-12 09:52:58
原文地址:Linux 管理之内存篇 作者:Mr__zhang
一、概念
Linux的内存分为物理内存和虚拟内存,物理内存即是插在主板上的所有内存的总和,而虚拟内存(Virtual Memory)是采用硬盘对物理内存的一种扩展,当物理内存不够使用时,内核会将物理内存中未使用的一部分内如的内容写入到硬盘上,将空闲的这部分内存用于其它用途,当再一下需要原始内容时,将硬盘上的内容读入内存,这就是Linux上的swap。但是硬盘的读写相对内存来说很慢(大约1000倍),所以涉及到swap操作的程序运行速度无法运行很快,如果条件允许可以加大物理内存总量,禁用swap。
Linux内部的最小内存分配单元为page,每个page的大小一般为4K, 可通过以下命令获取page的大小:getconf PAGE_SIZE,虚拟内存的基本单位也为Page,它被分为很多的Page,在X86中一个Page为4KB。当内核写内存到硬盘或者读磁盘到内存,这就是一次与Memory Swaping;内存分页(Memory Paging)是指内核会定期将内存中的数据同步到硬盘,所以它一直是在活跃运行的。
随着程序不断运行,不断消耗内存,内核就必须经常扫描内存空间收回和释放内存空间,内核采用PFRA(Page Frame Reclaim Algorithm)页面回收算法来回收和释放内存空间,内存页有几下几个类型:
(1) Unreclaimable: 锁定的内存保留页;
(2) Swappable:匿名的内存页;
(3) Syncable:通过硬盘文件备份的内存页;
(4) Discardable:静态页和被丢弃的页。
除了第一种之外,都可以被PFRA进行回收。
二、进程
1. kswapd进程
它负责确保系统空闲物理内存的数量在一个合适的范围,它监控内核中的pages_high和pages_low阙值。如果空闲内存的数值低于pages_low,则每次kswapd进程启动扫描并尝试释放32个free pages。并一直重复这个过程,直到空闲内存的数值高于pages_high。在物理内存严重不足的情况下,会导致系统频繁调用kswapd进程, 引起I/O严重等待.整个系统处于假死状态.kswapd进程会过度占用CPU。
Kswapd进程完成以下几个操作:
(1) 如果该页处于未修改状态,则将该页放置回空闲列表中;
(2) 如果该页处于已修改状态并备份回文件系统,则将页内容写入到磁盘;
(3) 如果该页处于已修改状态但没有任何磁盘备份,则将页内容写入懂啊swap area;
2. pdflush进程
它用来同步文件相关的内存页面,把内存页面及时同步到硬盘上,在Linux系统中,写操作是异步的,即写操作返回的时候数据并没有真正写到磁盘上,而是先写到了系统cache里,随后由pdflush内核线程将系统中的脏页(由于内存中页缓存的缓存作用,写操作实际上都是延迟的,当页缓存中的数据比磁盘存储的数据还要新时,那么该数据就被称为脏页)写到磁盘上。
三、相关工具
1. free、top
Linux中使用free可以查看系统内存使用状态,默认单位为Kb。
Mem 行显示了从系统角度看来内存使用的情况
total是系统可用的内存大小, 数量上等于系统物理内存减去内核保留的内存
buffers和cached是系统用做缓冲的内存
buffers与某个块设备关联,包含了文件系统元数据
buffer中放的是对象数据结构, 并且跟踪了块的变化
cache只包含了文件本身,cached中放的是无结构的块数据。
-/+ buffers/cache行则从用户角度显示内存信息,可用内存从数量上等于mem行used列值减去buffers和cached内存的大小。因为buffers和cached是操作系统为加快系统运行而设置的,当用户需要时,可以直接为用户使用。
Linux第一次读取一个文件运行时,一份放到一片内存中cache起来,另一份放入运行程序的内存中正常运行,当程序运行完关闭。Cache中的那一份却没有释放第二次运行的时候,系统先看看在内存中是否有一次运行时存起来的cache中的副本,如果有的话,直接从内存中读取,那样,速度就快多了。如果cache占用的内存过多了,影响正常运行程序需要的内存,那么会释放掉一部分cache内存,但是总量会保持一个很高的值,所以,Linux总是能最大限度的使用内存,就算加到16G,32G内存,也会随着不断的IO操作,内存的free值会慢慢减少到只有几M,所以说linux下内存的used经常很大。
所以可以得到以下等式:
Total mem=Free mem+Used mem
Used mem=内核表使用+程序使用物理内存+Buffer mem+Cached mem
程序使用内存=Used – Buffer- Cached – 内核使用(可以忽略);因此一个程序一次可申请的内存<=Free + Buffer +Cached
2. vmstat
vmstat 命令报告关于内核线程、虚拟内存、磁盘、陷阱和 CPU 活动的统计信息,语法规则:
语法:vmstat [- V][- n][delay[count]
- V 的打印版本。
- n 的原因不得转载定期的头。
- a 打印不活跃/活跃页面统计。
- d打印磁盘统计
- D三维打印磁盘表
- p打印磁盘分区统计
- s打印VM表
- m打印slabinfo
- S的单位大小
delay是在几秒钟的更新之间的延迟。单位大小K:1000 K:1024米:1000000 M:1048576(默认是K)
count是更新的数量。
Vmstat输出字段说明
Swapd:当前虚拟内存使用的总额(单位:KB)。空闲内存到达到最低的阙值,更多的数据被转换成虚拟内存页到swap area中;
Free:当前内存中可用空间字节数;
Buffer:当前内存中用于read()和write()操作的缓冲区缓存字节数;
Cache:当前内存中映射到进程地址空间字节数;
So:写入交换空间的字节数总额;
Si:从交换空间写回内存的字节数总额;
Bo:磁盘块页面从内存到文件或交换设备的总额;
Bi:磁盘页面从文件或交换设备到内存的总额;
inactive: vmstat -a查看(什么意思没弄明白);
active:vmstat -a查看(什么意思没弄明白);
3. 查看系统实际内存大小
命令dmesg |grep [mM][eE][mM]
找到输出中的Memory: 2042524k/2086248k available,其中后面的为物理实际内存大小,而前面为系统可用内存大小,即去掉了内核占用内存、保留内存、数据缓存以后的可用内存(大约45M)。
4. 其它命令
cat /proc/meminfo: 机器的内存使用信息,内存的一些额定值;
cat /proc/pid/maps: pid为进程号,显示当前进程所占用的虚拟地址;
cat /proc/pid/statm:进程所占用的内存。
cat /proc/self/statm 输出以下结果
654 57 44 0 0 334 0
输出解释
CPU 以及CPU0。。。的每行的每个参数意思(以第一行为例)为:
参数 解释 /proc//status
Size (pages) 任务虚拟地址空间的大小 VmSize/4
Resident(pages) 应用程序正在使用的物理内存的大小 VmRSS/4
Shared(pages) 共享页数 0
Trs(pages) 程序所拥有的可执行虚拟内存的大小 VmExe/4
Lrs(pages) 被映像到任务的虚拟内存空间的库的大小 VmLib/4
Drs(pages) 程序数据段和用户态的栈的大小 (VmData+ VmStk )4
dt(pages) 04