教你认识Linux内存管理方式,分析Swap被程序占用情况

关键字:教你认识Linux内存管理方式,分析Swap被程序占用情况

一、先了解一下linux对内存的管理方式:

在Linux里(别的系统也差不多),内存有物理内存和虚拟内存之说,物理内存是什么自然无需解释,虚拟内存实际是物理内存的抽象,多数情况下,出于方便性的考虑,程序访问的都是虚拟内存地址,然后操作系统会把它翻译成物理内存地址。很多人会把虚拟内存和Swap混为一谈,实际上Swap只是虚拟内存引申出的一种技术而已:操作系统一旦物理内存不足,为了腾出内存空间存放新内容,就会把当前物理内存中的内容放到交换分区里,稍后用到的时候再取回来,需要注意的是,Swap的使用可能会带来性能问题,偶尔为之无需紧张,糟糕的是物理内存和交换分区频繁的发生数据交换,这被称之为Swap颠簸,一旦发生这种情况,先要明确是什么原因造成的,如果是内存不足就好办了,加内存就可以解决,不过有的时候即使内存充足也可能会出现这种问题,比如MySQL就有可能出现这样的情况,解决方法是限制使用Swap:

shell>sysctl-wvm.swappiness=0查看内存情况最常用的是free命令:

shell>free-m

totalusedfreesharedbufferscached

Mem:32101293772723023925880

-/+buffers/cache:325828842

Swap:204702047

新手看到used一栏数值偏大,free一栏数值偏小,往往会认为内存要用光了。其实并非如此,之所以这样是因为每当我们操作文件的时候,Linux都会尽可能的把文件缓存到内存里,这样下次访问的时候,就可以直接从内存中取结果,所以cached一栏的数值非常的大,不过不用担心,这部分内存是可回收的,操作系统会按照LRU算法淘汰冷数据。除了cached,还有一个buffers,它和cached类似,也是可回收的,不过它的侧重点在于缓解不同设备的操作速度不一致造成的阻塞,这里就不多做解释了。

知道了原理,我们就可以推算出系统可用的内存是free+buffers+cached:

shell>echo"2723+239+25880"|bc-l

28842

至于系统实际使用的内存是used–buffers–cached:

shell>echo"29377-239-25880"|bc-l

3258

除了free命令,还可以使用sar命令:

shell>sar-r

kbmemfreekbmemused%memusedkbbufferskbcached

32243922964773290.1924611626070160

31163242975580090.5224599226157372

29595202991260491.0024555626316396

27922483007987691.5124568026485672

27182603015386491.7324568426563540

shell>sar-W

pswpin/spswpout/s

0.000.00

0.000.00

0.000.00

0.000.00

0.000.00

二、简单命令方式查看swap被那些进程占用:

简单脚本递归,列出swap使用pid,top10

foriin$(cd/proc;ls|grep"^[0-9]"|awk'$0>100');doawk'/Swap:/{a=a+$2}END{print'"$i"',a/1024"M"}'/proc/$i/smaps2>/dev/null;done|sort-k2nr|head-10

查看指定进程所使用的swap命令:

awk'/^Swap:/{SWAP+=$2}END{printSWAP"KB"}'/proc/$(pid)/smaps

三、查看所有进程占用情况swap的脚本:

#!/bin/bash

#Getcurrentswapusageforallrunningprocesses

#writtedbyxly

functiongetswap{

SUM=0

OVERALL=0

forDIRin`find/proc/-maxdepth1-typed|egrep"^/proc/[0-9]"`;do

PID=`echo$DIR|cut-d/-f3`

PROGNAME=`ps-p$PID-ocomm--no-headers`

forSWAPin`grepSwap$DIR/smaps2>/dev/null|awk'{print$2}'`

do

letSUM=$SUM+$SWAP

done

echo"PID=$PID-Swapused:$SUM-($PROGNAME)"

letOVERALL=$OVERALL+$SUM

SUM=0

done

echo"Overallswapused:$OVERALL"

}

getswap

#getswap|egrep-v"Swapused:0"

相关推荐