本文转载自微信公众号《DBA的杂念录》,作者潇湘隐士。转载本文请联系DBA杂念公众号。在Linux中,有很多命令或工具可以用来查看内存使用情况。今天我们将简单讨论一下如何查看进程消耗和内存使用情况。Linux内存管理及相关概念比Windows复杂。在此之前,我们需要先了解一下Linux系统中与内存相关的专用名词和术语概念:物理内存和虚拟内存物理内存:是系统硬件提供的内存大小,也就是真实的内存,一般称为内存条.也叫随机存取存储器(randomaccessmemory,RAM),又称“随机存取存储器”,是一种直接与CPU交换数据的内部存储器,也叫主存储器(memory)。虚拟内存:相对于物理内存,Linux下有一个虚拟内存的概念。虚拟内存是为满足物理内存不足而提出的一种策略。它是使用磁盘空间虚拟出的一块逻辑内存,用作虚拟内存。磁盘空间称为交换空间(SwapSpace)。linux会在物理内存不足的时候使用虚拟内存,内核会将暂时不用的内存块信息写入虚拟内存,这样物理内存就会被释放,这块内存就可以做他用了,这当需要使用内容加载时,信息会从虚拟内存中重新读取到物理内存中。Linuxbuffers和cached经常会发现Linux系统中空闲内存很少。似乎所有的记忆都被耗尽了。从表面上看,似乎是内存不够用。很多新手一看到内存“耗尽”就很紧张,其实这是因为Linux系统使用空闲内存作为磁盘文件数据的缓存。这会导致您的系统看起来处于内存非常紧张的状态。但事实并非如此。这与Windows的内存管理不同。Linux将使用空闲内存作为缓存和缓冲区。Buffers是指用于块设备的缓冲区大小(块设备的读写缓冲区)。它只记录文件系统的元数据和跟踪飞行中的页面。缓冲区与特定的块设备相关联,涵盖文件系统元数据的缓存以及跟踪飞行中的页面。缓存仅包含停放的文件数据。也就是说,缓冲区会记住目录中的内容、文件权限,并跟踪特定块设备正在写入或读取的内存。缓存只包含文件本身的内容。cached是页面缓存的内存和文件系统的缓存。当你读写文件时,Linux内核会将文件缓存在内存中,以提高读写的性能和速度。这部分内存就是CacheMemory(缓存内存)。即使你的程序运行完毕,CacheMemory也不会自动释放。这会导致你在Linux系统中程序频繁读写文件后,发现可用的物理内存会非常少。其实际缓存内存(CacheMemory)在你需要使用内存的时候会自动释放,所以你不必担心没有内存可用Cached是页面缓存的大小。Buffers是内存块I/O缓冲区的大小。缓存事项;Buffers在很大程度上是无关紧要的。Cached是Linux页面缓存的大小减去交换缓存中的内存,它由SwapCached表示(因此总页面缓存大小为Cached+SwapCached)。Linux通过页面缓存执行所有文件I/O。写入是通过简单地将页面缓存中的相应页面标记为脏来实现的;刷新器线程然后定期将所有脏页写回磁盘。读取是通过从页面缓存中返回数据来实现的;如果数据尚未在缓存中,则首先填充它。在现代Linux系统上,缓存很容易达到几千兆字节。它只会在内存压力时收缩。系统将清除页面缓存并将数据换出到磁盘,以便根据需要提供更多内存。缓冲区处于-内存块I/O缓冲区。它们的寿命相对较短。在Linux内核版本2.4之前,Linux具有单独的页面和缓冲区缓存。从2.4开始,页面和缓冲区缓存是统一的,缓冲区是未在页面缓存中表示的原始磁盘块——即,不是文件数据。因此,缓冲区指标的重要性微乎其微。在大多数系统上,Buffers通常只有几十兆字节。Linux共享内存共享内存是进程间通信最简单的方式之一共享内存允许两个或多个进程访问同一块内存,就像malloc()函数将指向同一物理内存区域的指针返回给不同的进程一样。当一个进程改变这个地址的内容时,其他进程会注意到这一点。所谓共享内存其实就是多个进程共享同一个物理内存空间,是通过将同一个物理内存映射到不同进程的虚拟空间来实现的。由于映射到不同进程的虚拟空间,不同进程可以直接使用,不需要像消息队列那样进行复制,所以共享内存的效率非常高。共享内存可以通过mmap()映射普通文件来实现,也可以通过SystemV的共享内存机制来实现。SystemV通过映射特殊文件系统shm中的文件实现进程间的共享内存通信,也就是说,每个共享内存内存区域对应特殊文件系统shm中的一个文件。另外,还要了解RSS、PSS、USS等相关概念:VSS--VirtualSetSize虚拟内存消耗(包括共享库占用的内存)RSS--ResidentSetSize实际使用物理内存(包括共享库占用的内存)PSS--ProportionalSetSizeactuallyuses物理内存(按比例分配共享库占用的内存)USS--UniqueSetSize进程单独占用的物理内存(不包括共享库占用的内存)RSS(Residentsetsize),可以使用top命令,是最常用的内存指示器,表示进程占用的物理内存大小。但是,将各个进程的RSS值相加通常会超过整个系统的内存消耗,因为RSS包含了各个进程共享的内存。PSS(Proportionalsetsize)当所有使用共享库的程序共享共享库占用的内存时,每个进程占用的内存。显然所有进程的PSS之和就是系统的内存占用。会更准确一些,它把共享内存的大小平均,然后分配给各个进程。USS(Uniquesetsize)进程单独占用的内存在PSS中是属于自己的部分。它只计算进程单独占用的内存大小,不包括任何共享部分。所以下面介绍的命令,有的是查看进程的虚拟内存使用情况,有的是查看进程的RSS或者实际物理内存。我们会在告知的时候标注这些信息。top命令查看执行top命令后,执行SHIFT+F,可以选择按某列排序,比如选择n后,会按字段%MEM排序,当然也可以用shift+m或者大写键M让top命令按照字段%MEM来排序,当然你也可以按照VIRT(虚拟内存)、SWAP(进程使用的SWAP空间)、RES(实际使用的物理内存)来排序memory,当然你看到的实际内存很大因为这里是共享内存)%MEM--Memoryusage(RES)Atask'scurrentlyusedshareofavailablephysicalmemoryVIRT--virtualmemoryThetotalamountofvirtualmemoryusedbythetask.Itincludesallcode,dataandsharedlibrariespluspagesthathavebeenswapped.(注意:你可以定义STATSIZE=1environmentvariable/from#VIRT/willbecalculatedstateVmSizefield.)VIRT=SWAP+RESSWAP--Swappedsize(kb)Theswappedoutportionofatask'stotalvirtualmemoryimage.RES--Residentsize(kb)RES=CODE+DATA。有没有人奇怪为什么%MEM列的值加起来大于100?这是因为这里计算的是共享内存,因为有共享内存,你看到无论是VIRT还是RES的进程都非常高。由于大部分物理内存通常在多个应用程序之间共享,因此这种称为“使用的物理内存”(RSS,对应于top命令中的RES)的标准内存消耗指标可能会大大高估内存消耗。使用ps命令找出占用内存资源最多的20个进程(数量可以任意设置)#psaux|head-1;psaux|grep-vPID|sort-rn-k+4|head-20USERPID%CPU%MEMVSZRSSTTYSTATSTARTTIMECOMMANDoracle3214711.051.21325208012666320?RsAug24163:16ora_s000_SCM2oracle3214914.250.91325034412594264?SsAug24210:41ora_s001_SCM2oracle321534.249.61325082012279432?SsAug2462:27ora_s003_SCM2oracle321552.548.61325026812040732?SsAug2438:21ora_s004_SCM2oracle321571.244.51325029611011708?SsAug2418:31ora_s005_SCM2oracle321512.739.7133504369829944?SsAug2441:18ora_s002_SCM2oracle321590.538.9132507049625764?SsAug248:18ora_s006_SCM2oracle321610.226.3132506686507244?SsAug243:38ora_s007_SCM2oracle321290.025.5132990846324644?SsAug241:25ora_dbw0_SCM2oracle321810.015.8132501523913260?SsAug240:56ora_s017_SCM2oracle321452.715.3132552563786456?SsAug2440:11ora_d000_SCM2oracle321270.015.2132489963762860?SsAug240:05ora_mman_SCM2oracle321630.014.2132501083525160?SsAug241:04ora_s008_SCM2oracle321650.08.1132501722007704?SsAug240:37ora_s009_SCM2oracle321690.06.6132500601656864?SsAug240:08ora_s011_SCM2oracle321770.06.0132501481498760?SsAug240:12ora_s015_SCM2oracle321870.05.1132500841267384?SsAug240:06ora_s020_SCM2oracle321790.05.1132505841280156?SsAug240:05ora_s016_SCM2oracle321670.05.0132500601248668?SsAug240:08ora_s010_SCM2oracle321750.03.413250596857380?SsAug240:03ora_s014_SCM2#ps-eopmem,pcpu,rss,vsize,args|sort-k1-n-r|less查看进程实际占用的物理内存(实际物理内存大小与smem不同,这里解释一下:SIZE:进程使用的地址空间,如果进程映射了100M的内存,进程的地址空间会报100M内存.其实这个大小并不是一个程序实际使用的内存量.所以这里看到的内存和smem看到的大小不一样)ps-eosize,pid,用户、命令--排序大小|awk'{hr=$1/1024;printf("%13.2fMb",hr)}{for(x=4;x<=NF;x++){printf("%s",$x)}打印""}'|cut-d""-f2|cut-d"-"-f1psaux|awk'{print$6/1024"MB\t\t"$11}'|sort-nsmem命令查看smem命令,这里不介绍,直接参考链接Linux监控工具介绍系列-smem#smem-rspsspmap命令查看#ps-ef|greptomcat#pmap32341#pmap-x32341可以使用-x选项提供memor的信息y每个映射的分配和映射类型。显示每个映射的常驻、非共享匿名和锁定内存量网上有一个python脚本可以查看程序或进程的内存使用情况。地址在https://raw.githubusercontent.com/pixelb/ps_mem/master/ps_mem.pythonps_mem.py[root@mylnx03~]#pythonps_mem。py-h用法:ps_mem[OPTION]...Showprogramcorememoryusage-h,-helpShowthishelp-p
