linux下,一個運行中的程序,究竟佔用了多少內存

linux下,一個運行中的程序,究竟佔用了多少內存

1. 在linux下,查看一個運行中的程序, 佔用了多少內存, 通常的命令有php

   (1). ps aux:html

 

     其中  VSZ(或VSS)列 表示,程序佔用了多少虛擬內存。linux

           RSS列 表示, 程序佔用了多少物理內存。ios

           虛擬內存能夠不用考慮,它並不佔用實際物理內存。程序員

   (2). top 命令也能夠緩存

     其中  VIRT(或VSS)列  表示,程序佔用了多少虛擬內存。 同 ps aux 中的 VSZ列app

           RES列 表示, 程序佔用了多少物理內存。同 ps aux 中的RSS列ide

           

2.在linux下, 查看當前系統佔用了多少內存, 通常的命令是  free函數

其中, free就是系統還有多少內存可使用。post

但因爲 linux 系統對內存使用有一個原則, 就是, 內存是寶貴的, 能使用多少就使用多少。 因此, linux會把已經調用過的包緩存起來,放在內存裏。

這樣,實際上,可使用的內存,就能夠理解爲, free+buffers+cached

 

3.當你瞭解完這些命令之後, 再去使用ps aux 命令去查看的時候, 會發現一個奇怪的現象。

 全部的  RSS 列的數據,加起來, 比物理內存的數要大不少。

 好比, 物理內存爲2G, 而RSS列的數據加起來,可能有5個G之多, 這是怎麼回事了?

 

 這是由於RSS列的值騙了咱們。 

 

 linux的內存機制是這樣的:

 在運行一個程序時, linux會調用該程序依賴的連接庫, 如lib.xx.so。 首先看該連接庫是否被映射進內存中,若是沒有被映射,則將代碼段與數據段映射到內存中,不然只是將其加入進程的地址空間。

 

 這樣,當N個程序,依賴到lib.xx.so的時候, 實際上,內存中只有一個lib.xx.so ,而不是N個。 

 

 而RSS在顯示一個程序佔用的實際物理內存時, 將lib.xx.so也算了進來。

 

 好比, X程序, 自己佔用內存爲5M, lib.xx.so 佔用內存2M,lib.xx.so被N個程序共享依賴。 則RSS顯示爲,X程序運行,佔用內存爲7M。 實際上, X程序佔用了5M空間。 多餘的2m被討入到RSS中了。

 

 當你在用ps aux顯示內存佔用狀況時, N個共享依賴lib.xx.so的N個程序,都把這2m空間,算在本身的RSS中了, 這樣RSS的sum值,就比實際物理內存多了。

 

 固然, linux的內存使用機制很複雜, 不是一句兩句能說清楚的。這裏只是簡單的說明了一下, ps aux中的RSS值, 並不能真實反映物理內存的使用狀況。

 

4. 若是查看更詳細的內存使用狀況, 可用如下幾種方法, 或者幾種方法結合使用:

這幾種方法,都須要root帳戶的權限

 

(1). pmap -d $pid 

$pid 是正在運行的程序的pid

 

(2). cat /proc/$pid/smaps

  smaps的數據比較詳細,可簡單的概括一下,概括的命令以下:

  cat /proc/$pid/smaps  | awk '/Size|Rss|Pss|Shared|Private|Referenced|Swap/{val_name=gensub(/([a-zA-Z_]*).*/,"\\1",1,$1); list[val_name]+=$2; }END{for(val in list)print val,list[val];}'                     

(3). cat /proc/$pid/maps

 

(4). cat /proc/$pid/statm

輸出解釋

第一列  size:任務虛擬地址空間大小
第二列  Resident:正在使用的物理內存大小
第三列  Shared:共享頁數
第四列  Trs:程序所擁有的可執行虛擬內存大小
第五列  Lrs:被映像倒任務的虛擬內存空間的庫的大小
第六列  Drs:程序數據段和用戶態的棧的大小
第七列 dt:髒頁數量

(5). vmstat

這個命令聽說也能夠提供一些參考信息,具體還未研究

 

5.做爲phper,嘗試過使用php的函數memory_get_usage(), 該函數也不能獲得php當前運行的程序,實際的,真正佔用的內存數量。

  若是真想獲得,php真正佔用的內存, 大概只能在, 程序運行的開始,執行一次memory_get_usage().

  在程序運行結束,執行一次memory_get_usage()。 將二者的值相減,獲得的值, 應該是一個相對比較準確的,內存佔用數量了。

  這個方法尚未測試, 考慮到, 獲得這個數量,也沒有實際意義, 加上平時又比較忙,懶得試了。

  

  也許php還有一個方法, 是使用shm_* 系列函數, 這也我也未深刻研究,詳見這篇文章(http://duckweeds.blog.sohu.com/166663796.html)

  

 6.另外還有一些文章能夠參考,以下:

 (1)一個C程序員, 眼中的Linux內存使用詳解,寫的比較詳細,比較細緻,也比較專業。

 (2)對 /proc/pid/statm的詳細說明

 (3)簡單解讀linux的/proc下的statm、maps、memmap 內存信息文件分析

 (4)php 共享內存的使用

 (5)Memory Usage with smaps

 (6)Capturing Process Memory Usage Under Linux,這篇文章彷佛是對一個產品的廣告,但裏面對USS,PSS,RSS 這幾個概念有詳細的解釋

 (7) ELC: How much memory are applications really using跟(6)同樣,是對同一個產品的廣告,文章裏有一些東西能夠參考

(8) Linux Check Memory Usage,文章對 free, vmstat,top , gnome-system-monitor等命令有一些介紹

(9)Console Monitoring Tools for SUSE Linux,對top,free,uptime,pmap,smartctl,iostat,strace等命令有所介紹,而且介紹的比較詳細,目前只是粗略的看了一下,有時間還要再看看。 

(10)Solaris 9 Enhanced pmap,比較詳細的介紹了pmap的應用,不過是基於Solaris 9的

相關文章
相關標籤/搜索