一、背景
在Linux中摇予,有很多命令或工具查看內(nèi)存使用情況,今天我們來(lái)看看如何查看進(jìn)程消耗吗跋、占用的內(nèi)存情況侧戴,Linux的內(nèi)存管理和相關(guān)概念要比Windows復(fù)雜一些。
物理內(nèi)存和虛擬內(nèi)存?
物理內(nèi)存:就是系統(tǒng)硬件提供的內(nèi)存大小小腊,是真正的內(nèi)存救鲤,一般叫做內(nèi)存條。也叫隨機(jī)存取存儲(chǔ)器(random access memory秩冈,RAM)又稱(chēng)作“隨機(jī)存儲(chǔ)器”,是與CPU直接交換數(shù)據(jù)的內(nèi)部存儲(chǔ)器斥扛,也叫主存(內(nèi)存)入问。?
虛擬內(nèi)存:相對(duì)于物理內(nèi)存,在Linux下還有一個(gè)虛擬內(nèi)存的概念稀颁,虛擬內(nèi)存就是為了滿(mǎn)足物理內(nèi)存的不足而提出的策略芬失,它是利用磁盤(pán)空間虛擬出的一塊邏輯內(nèi)存,用作虛擬內(nèi)存的磁盤(pán)空間被稱(chēng)為交換空間(Swap Space)匾灶。Linux會(huì)在物理內(nèi)存不足時(shí)棱烂,使用虛擬內(nèi)存,內(nèi)核會(huì)把暫時(shí)不用的內(nèi)存塊信息寫(xiě)到虛擬內(nèi)存阶女,這樣物理內(nèi)存就得到了釋放颊糜,這塊兒內(nèi)存就可以用于其他目的,而需要用到這些內(nèi)容的時(shí)候秃踩,這些信息就會(huì)被重新從虛擬內(nèi)存讀入物理內(nèi)存衬鱼。?
Linux的buffers與cached
在Linux中經(jīng)常發(fā)現(xiàn)空閑的內(nèi)存很少,似乎所有的內(nèi)存都被消耗殆盡了憔杨,表面上看是內(nèi)存不夠用了鸟赫,很多新手看到內(nèi)存被“消耗殆盡”非常緊張,其實(shí)這個(gè)是因?yàn)長(zhǎng)inux系統(tǒng)將空閑的內(nèi)存用來(lái)做磁盤(pán)文件數(shù)據(jù)的緩存。這個(gè)導(dǎo)致你的系統(tǒng)看起來(lái)處于內(nèi)存非常緊急的狀況抛蚤。但是實(shí)際上不是這樣台谢。這個(gè)區(qū)別于Windows的內(nèi)存管理。Linux會(huì)利用空閑的內(nèi)存來(lái)做cached & buffers岁经。?
buffers是指用來(lái)給塊設(shè)備做的緩沖大卸月怠(塊設(shè)備的讀寫(xiě)緩沖區(qū)),它只記錄文件系統(tǒng)的metadata以及 tracking in-flight pages.
cached是作為page cache的內(nèi)存, 文件系統(tǒng)的cache蒿偎。你讀寫(xiě)文件的時(shí)候朽们,Linux內(nèi)核為了提高讀寫(xiě)性能與速度,會(huì)將文件在內(nèi)存中進(jìn)行緩存诉位,這部分內(nèi)存就是Cache Memory(緩存內(nèi)存)骑脱。即使你的程序運(yùn)行結(jié)束后,Cache Memory也不會(huì)自動(dòng)釋放苍糠。這就會(huì)導(dǎo)致你在Linux系統(tǒng)中程序頻繁讀寫(xiě)文件后叁丧,你會(huì)發(fā)現(xiàn)可用物理內(nèi)存會(huì)很少。其實(shí)這緩存內(nèi)存(Cache Memory)在你需要使用內(nèi)存的時(shí)候會(huì)自動(dòng)釋放岳瞭,所以你不必?fù)?dān)心沒(méi)有內(nèi)存可用
Linux共享內(nèi)存
共享內(nèi)存是進(jìn)程間通信中最簡(jiǎn)單的方式之一拥娄。共享內(nèi)存允許兩個(gè)或更多進(jìn)程訪問(wèn)同一塊內(nèi)存,就如同 malloc() 函數(shù)向不同進(jìn)程返回了指向同一個(gè)物理內(nèi)存區(qū)域的指針瞳筏。
當(dāng)一個(gè)進(jìn)程改變了這塊地址中的內(nèi)容的時(shí)候稚瘾,其它進(jìn)程都會(huì)察覺(jué)到這個(gè)。其實(shí)所謂共享內(nèi)存姚炕,就是多個(gè)進(jìn)程間共同地使用同一段物理內(nèi)存空間摊欠,它是通過(guò)將同一段物理內(nèi)存映射到不同進(jìn)程的虛擬空間來(lái)實(shí)現(xiàn)的。由于映射到不同進(jìn)程的虛擬空間中柱宦,不同進(jìn)程可以直接使用些椒,不需要像消息隊(duì)列那樣進(jìn)行復(fù)制,所以共享內(nèi)存的效率很高掸刊。共享內(nèi)存可以通過(guò)mmap()映射普通文件機(jī)制來(lái)實(shí)現(xiàn)免糕,也可以System V共享內(nèi)存機(jī)制來(lái)實(shí)現(xiàn),System V是通過(guò)映射特殊文件系統(tǒng)shm中的文件實(shí)現(xiàn)進(jìn)程間的共享內(nèi)存通信忧侧,也就是說(shuō)每個(gè)共享內(nèi)存區(qū)域?qū)?yīng)特殊文件系統(tǒng)shm中的一個(gè)文件石窑。
另外,我們還必須了解RSS苍柏、PSS尼斧、USS等相關(guān)概念:
VSS – Virtual Set Size 虛擬耗用內(nèi)存(包含共享庫(kù)占用的內(nèi)存)
RSS – Resident Set Size 實(shí)際使用物理內(nèi)存(包含共享庫(kù)占用的內(nèi)存)
PSS – Proportional Set Size 實(shí)際使用的物理內(nèi)存(比例分配共享庫(kù)占用的內(nèi)存)
USS – Unique Set Size 進(jìn)程獨(dú)自占用的物理內(nèi)存(不包含共享庫(kù)占用的內(nèi)存)
RSS(Resident set size),使用top命令可以查詢(xún)到试吁,是最常用的內(nèi)存指標(biāo)棺棵,表示進(jìn)程占用的物理內(nèi)存大小楼咳。但是,將各進(jìn)程的RSS值相加烛恤,通常會(huì)超出整個(gè)系統(tǒng)的內(nèi)存消耗母怜,這是因?yàn)镽SS中包含了各進(jìn)程間共享的內(nèi)存。
PSS(Proportional set size)所有使用某共享庫(kù)的程序均分該共享庫(kù)占用的內(nèi)存時(shí)缚柏,每個(gè)進(jìn)程占用的內(nèi)存苹熏。顯然所有進(jìn)程的PSS之和就是系統(tǒng)的內(nèi)存使用量。它會(huì)更準(zhǔn)確一些币喧,它將共享內(nèi)存的大小進(jìn)行平均后轨域,再分?jǐn)偟礁鬟M(jìn)程上去。?
USS(Unique set size )進(jìn)程獨(dú)自占用的內(nèi)存杀餐,它是PSS中自己的部分干发,它只計(jì)算了進(jìn)程獨(dú)自占用的內(nèi)存大小,不包含任何共享的部分史翘。?
二枉长、Linux內(nèi)存查看工具和命令
# yum -y install ps_mem
# yum info ps_mem
# rpm -ql ps_mem
# ps_mem -h
同一類(lèi)進(jìn)程占用,每個(gè)進(jìn)程占用
# ps -eo pmem,pcpu,rss,vsize,args | sort -k?1?-n -r | less
# ps -eo size,pid,user,command --sort -size | awk?'{ hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }'?|cut -d?""?-f2 | cut -d?"-"?-f1
# ps aux | awk?'{print $6/1024 " MB\t\t" $11}'?| sort -n
三琼讽、參考
使用ps必峰、top、ps_mem命令找出Linux中的最大內(nèi)存消耗過(guò)程
https://www.cnblogs.com/xuanbjut/p/12543636.html
ps_mem:一個(gè)用于精確報(bào)告 Linux 核心內(nèi)存用量的簡(jiǎn)單 Python 腳本
https://linux.cn/article-8639-1.html
ps_mem/ps_mem.py
https://github.com/pixelb/ps_mem/blob/master/ps_mem.py
Linux監(jiān)控工具介紹系列——smem
https://www.cnblogs.com/kerrycode/p/5079319.html
How can I measure the actual memory usage of an application or process?
https://stackoverflow.com/questions/131303/how-can-i-measure-the-actual-memory-usage-of-an-application-or-process