記憶體性能評估
Linux系統的記憶體分為實體記憶體和虛拟記憶體兩種。實體記憶體是真實的,也就是實體記憶體條上的記憶體。而虛拟記憶體則是采用硬碟空間補充實體記憶體,将暫時不使用的記憶體頁寫到硬碟上以騰出更多的實體記憶體讓有需要的程序使用。當這些已被騰出的記憶體頁需要再次使用時才從硬碟(虛拟記憶體)中讀回記憶體。這一切對于使用者來說是透明的。通常對Linux系統來說,虛拟記憶體就是swap分區
記憶體不足的表現:
- free memory急劇減少,回收buffer和cacher也無濟于事
- 大量使用交換分區(swpd)
- 頁面交換(swap)頻繁
- 讀寫磁盤數量(io)增多
- 缺頁中斷(in)增多
- 上下文切換(cs)次數增多
- 等待IO的程序數(b)增多
- 大量CPU時間用于等待IO(wa)
1.利用free指令監控記憶體
實際上來說,程式占用的真正記憶體就是:- buffers/cached 的數值。
程式角度上看未使用、可用的記憶體數:+ buffers/cached
是以看系統,真正已經用的記憶體數:used-(buffers+cached)的值。
真正未用到的記憶體數:free+buffers+cached 的值
經驗公式:
應用程式可用記憶體/系統實體記憶體>70%,表示系統記憶體資源非常充足,不影響系統性能;
應用程式可用記憶體/系統實體記憶體<20%,表示系統記憶體資源緊缺,需要增加系統記憶體;20%<應用程式可用記憶體/系統實體記憶體<70%,表示系統記憶體資源基本能滿足應用需求,暫時不影響系統性能
分析思路:
當 –/+ buffers/cache中的free長時間接近0,且 swap used長時間比較大時,說明實體記憶體已經不夠用了,需要更新記憶體或降低記憶體的使用量。
2.利用vmstat指令監控記憶體
swpd--切換到記憶體交換區的記憶體數量(k為機關)。如swpd值偶爾非0,不影響系統性能
free--目前空閑的實體記憶體數量(k為機關)
buff--buffers cache的記憶體數量,一般對塊裝置的讀寫才需要緩沖
cache--page cached的記憶體數量
一般作為檔案系統cached,頻繁通路的檔案都會被cached,如cache值較大,說明cached的檔案數較多,如果此時IO中bi比較小,說明檔案系統效率比較好。
si--由磁盤調入記憶體,也就是記憶體進入記憶體交換區的數量。
so--由記憶體調入磁盤,也就是記憶體交換區進入記憶體的數量。
si、so 兩列,表示磁盤和記憶體之間交換的頻繁程度。
1)si、so的值長期不為0,表示系統記憶體不足。需增加系統記憶體。
2)如果 si、so 數值長期很大并且free長期很小,表示實體記憶體不能滿足需要,也就是記憶體不足。由于磁盤的性能比記憶體是慢很多的,是以如果存在大量的頁面交換,那麼系統的性能必然會受到很大影響。
-swap:切換到交換記憶體上的記憶體(預設以KB為機關)
3)如果SWAP的值不為0,或者還比較大,比如超過100M了,但是SI,SO的值長期為0,這種情況我們可以不用擔心,不會影響系統性能。
3.利用sar監控記憶體
sar -r 1
顯示記憶體情況,其中commit顯示的是記憶體使用率
一、cat /proc/meminfo 檢視記憶體配置設定情況,這個檔案記錄着比較詳細的記憶體配置資訊
我們比較關心的是下面幾個字段:
MemTotal:系統總記憶體,由于 BIOS、核心等會占用一些記憶體,是以這裡和配置聲稱的記憶體會有一些出入。
MemFree:系統空閑記憶體。
MemAvailable:應用程式可用記憶體。有人會比較奇怪和 MemFree 的差別,可以從兩個層面來區分,MemFree 是系統層面的,而 MemAvailable 是應用程式層面的。系統中有些記憶體雖然被使用了但是有一部分是可以回收的,比如 Buffers、Cached 及 Slab 這些記憶體,這部分可以回收的記憶體加上 MemFree 才是 MemAvailable 的記憶體值,這是核心通過特定算法算出來的,是一個估算值。
Buffers:緩沖區記憶體
Cached:緩存
1. cat /proc/meminfo
2.MemTotal: 1019644 kB 所有可用RAM大小 (即實體記憶體減去一些預留位和核心的二進
3.制代碼大小)
4.MemFree: 119464 kB LowFree與HighFree的總和,被系統留着未使用的記憶體
5.Buffers: 110680 kB 用來給檔案做緩沖大小
6.Cached: 256796 kB 被高速緩沖存儲器(cache memory)用的記憶體的大小(等于
7.diskcache + SwapCache )
8.SwapCached: 0 kB
9.Active: 680560 kB 在活躍使用中的緩沖或高速緩沖存儲器頁面檔案的大小,除非
10.非常必要否則不會被移作他用
11.Inactive: 145228 kB 在不經常使用中的緩沖或高速緩沖存儲器頁面檔案的大小,可
12.能被用于其他途徑
13.Active(anon): 458208 kB
14.Inactive(anon): 280 kB
15.Active(file): 222352 kB
16.Inactive(file): 144948 kB
17.Unevictable: 0 kB
18.Mlocked: 0 kB
19.SwapTotal: 0 kB
20.SwapFree: 0 kB
21.Dirty: 92 kB 等待被寫回到磁盤的記憶體大小
22.Writeback: 0 kB 正在被寫回到磁盤的記憶體大小
23.AnonPages: 458328 kB 未映射頁的記憶體大小
24.Mapped: 27072 kB 裝置和檔案等映射的大小
25.Shmem: 176 kB
26.Slab: 53564 kB 核心資料結構緩存的大小,可以減少申請和釋放記憶體帶來的消耗
27.SReclaimable: 32404 kB 可收回Slab的大小
28.SUnreclaim: 21160 kB 不可收回Slab的大小(SUnreclaim+SReclaimable=Slab)
29.KernelStack: 1136 kB 核心棧大小占用的記憶體
30.PageTables: 5856 kB 管理記憶體分頁頁面的索引表的大小
31.NFS_Unstable: 0 kB 不穩定頁表的大小
32.Bounce: 0 kB
33.WritebackTmp: 0 kB
34.CommitLimit: 509820 kB
35.Committed_AS: 1483868 kB
36.VmallocTotal: 34359738367 kB 可以vmalloc虛拟記憶體大小
37.VmallocUsed: 7472 kB 已經被使用的虛拟記憶體大小
38.VmallocChunk: 34359728764 kB
39.HardwareCorrupted: 0 kB
40.AnonHugePages: 198656 kB
41.HugePages_Total: 0
42.HugePages_Free: 0
43.HugePages_Rsvd: 0
44.HugePages_Surp: 0
45.Hugepagesize: 2048 kB
46.DirectMap4k: 7168 kB
47.DirectMap2M: 1044480 kB
二、free -m 檢視記憶體使用情況(-m:以M顯示;-g:以G顯示;-h:以比較直覺的值
機關顯示)
MemTotal = used + free + buff/cache
shared 字段,這個是多程序的共享記憶體空間
三、檢視程序占用的記憶體情況:ps aux|awk '{sum+=$6} END {print sum/1024}'
四、top
top 指令運作時預設是按照 CPU 使用率進行排序的,如果要按照記憶體排序,該怎麼操作呢?兩種方法,一種直接按 “M”(相應的按 “P” 是 CPU),另外一種是在鍵入 top 之後,按下 “F”,然後選擇要排序的字段,再按下 “s” 确認即可。
可以看到,我按照 “%MEM” 排序的結果。這個結果對于檢視系統占用記憶體較多的哪些程序是比較有用的。
然後這裡我們會重點關注幾個地方,上面橫排區,和前面幾個指令一樣可以檢視系統記憶體資訊,中間标注的橫條部分,和記憶體相關的有三個字段:VIRT、RES、SHR。
VIRT:virtual memory usage,程序占用的虛拟記憶體大小。
RES:resident memory usage,程序常駐記憶體大小,也就是實際記憶體占用情況,一般我們看程序占用了多少記憶體,就是看的這個值。
SHR:shared memory,共享記憶體大小,不常用。
五、ps
ps 同樣可以檢視程序占用記憶體情況,一般常用來檢視 Top n 程序占用記憶體情況,如:
ps aux --sort=rss | head -n,表示按 rss 排序,取 Top n。
這裡也關注三個字段:
%MEM:程序使用實體記憶體所占百分比。
VSZ:程序使用虛拟記憶體大小。
RSS:程序使用實體記憶體大小,我們會重點關注這個值。
檢視更詳細的記憶體占比:cat /proc/pid/status(VmRSS為記憶體)
五、vmstat 1
swpd 虛拟記憶體已使用的大小,如果大于0,表示你的機器實體記憶體不足了,如果不是程式記憶體洩露的原因,那麼你該更新記憶體了或者把耗記憶體的任務遷移到其他機器。
free 空閑的實體記憶體的大小。
buff Linux/Unix系統是用來存儲,目錄裡面有什麼内容,權限等的緩存
cache cache直接用來記憶我們打開的檔案,給檔案做緩沖,(這裡是Linux/Unix的聰明之處,把空閑的實體記憶體的一部分拿來做檔案和目錄的緩存,是為了提高 程式執行的性能,當程式使用記憶體時,buffer/cached會很快地被使用。)
si 每秒從磁盤讀入虛拟記憶體的大小,如果這個值大于0,表示實體記憶體不夠用或者記憶體洩露了,要查找耗記憶體程序解決掉。
so 每秒虛拟記憶體寫入磁盤的大小,如果這個值大于0,同上。
bi 塊裝置每秒接收的塊數量,這裡的塊裝置是指系統上所有的磁盤和其他塊裝置,預設塊大小是1024byte,但是我曾在處理拷貝大量資料(2-3T)的機器上看過可以達到140000/s,磁盤寫入速度差不多140M每秒
bo 塊裝置每秒發送的塊數量,例如我們讀取檔案,bo就要大于0。bi和bo一般都要接近0,不然就是IO過于頻繁,需要調整。
六:pmap -x pid檢視程序的記憶體映像資訊,能夠看程序在哪些地方用了多少記憶體
可以看到該程序記憶體被哪些庫、哪些檔案所占用,據此我們定位程式對記憶體的使用。
幾個字段介紹一下:
Address:占用記憶體的檔案的記憶體起始位址。
Kbytes:占用記憶體的位元組數。
RSS:實際占用記憶體大小。
Dirty:髒頁大小。
Mapping:占用記憶體的檔案,[anon] 為已配置設定的記憶體,[stack] 為程式堆棧
最後的 total 為統計的總值
隻顯示最後一行total的值:pmap -x pid | tail -1
循環顯示最後一行total的值:while true; do pmap -x pid | tail -1; sleep 1; done
pmap -d 14596根據程序檢視程序相關資訊占用的記憶體情況
mapped 表示該程序映射的虛拟位址空間大小,也就是該程序預先配置設定的虛拟記憶體大小,即ps出的vsz
writeable/private 表示程序所占用的私有位址空間大小,也就是該程序實際使用的記憶體大小
shared 表示程序和其他程序共享的記憶體大小
七、dmidecode -t memory記憶體設定情況
八、nmon
/proc/meminfo顯示的結果非常詳細也非常直覺,不過我們平時關心的主要就那幾個,而且顯示如此多,很多一些重要的東西就忽略掉了,這裡可以借助IBM出的工具nmon來檢視記憶體配置設定情況。如下圖:
從上面這個輸出,也可以看到主要記憶體還是被active占用的。其次是cached和buffers 。其他幾塊并沒有占用多少記憶體。
注意:SecureCRT下nmon會有亂碼出現,通過将終端類型修改為vt100并重連就OK了。
九、slabtop
objs是指對象的個數,obj_size為對象的大小,use是使用的百分比,這個百分比是針對後面的cache_size來說的。cache_size是給kmem_cache所有對象配置設定的總大小。我們可以将slabtop檢視到的結果與/proc/slabinfo的結果做一個對比,如下,其中/proc/slabinfo中的第三列與第四列的值為num_objs和objsize。這裡通過slabtop取得的cache_size乘百分比得到的結果和/proc/slabinfo 3、4列乘積求和得到的結果基本相同
JDK本身提供了很多友善的JVM性能調優監控工具,除了jps、jstat、jinfo、jmap、jhat、jstack等小巧的工具,還有內建式的jvisualvm和jconsole
jps #JVM Process Status Tool,顯示指定系統内所有的HotSpot虛拟機程序。
jstat #JVM statistics Monitoring是用于監視虛拟機運作時狀态資訊的指令,它可以顯示出虛拟機程序中的類裝載、記憶體、垃圾收集、JIT編譯等運作資料。
jmap #JVM Memory Map指令用于生成heap dump檔案。
jhat #JVM Heap Analysis Tool指令是與jmap搭配使用,用來分析jmap生成的dump,jhat内置了一個微型的HTTP/HTML伺服器,生成dump的分析結果後,可以在浏覽器中檢視。
jstack #用于生成java虛拟機目前時刻的線程快照。
jinfo #JVM Configuration info 這個指令作用是實時檢視和調整虛拟機運作參數。
javap #檢視經javac之後産生的JVM位元組碼代碼,自動解析.class檔案, 避免了去了解class檔案格式以及手動解析class檔案内容。
jcmd #幾乎集合了jps、jstat、jinfo、jmap、jstack所有功能,一個多功能工具, 可以用來導出堆, 檢視Java程序、導出線程資訊、 執行GC、檢視性能相關資料等。
jps
jps(JVM Process Status Tool,虛拟機程序監控工具),這個指令可以列出正在運作的虛拟機程序,并顯示虛拟機執行主類名稱,以及這些程序的本地虛拟機唯一ID。這個ID被稱為本地虛拟機唯一ID(local virtual Machine Identifier,簡寫為LVMID)。如果你在linux的一台伺服器上使用jps得到的LVMID其實就是和ps 指令得到的PID是一樣的。
jstat -gcutil pid 1000 #顯示輸出垃圾收集統計資訊
S0:幸存者0空間使用率占空間目前容量的百分比。
S1:幸存者1空間使用率占空間目前容量的百分比。
E: Eden空間使用率占空間目前容量的百分比。
O:舊空間使用率占空間目前容量的百分比。
M:Metaspace使用率占空間目前容量的百分比。
CCS:壓縮類空間使用率,以百分比表示。
YGC:年輕一代GC事件的數量。
YGCT:年輕一代的垃圾收集時間(S)。
FGC:完整的GC事件的數量。
FGCT:完整的垃圾收集時間(S)。
GCT:垃圾收集總時間(S)。
jstat -gcnew -h3 pid 1000 #顯示pid 的1000毫秒為時間間隔,每三行輸出标題的統計新生代的行為
S0C:目前幸存者空間0容量(kB)。
S1C:目前幸存者空間1容量(kB)。
S0U:幸存者空間0使用率(kB)。
S1U:幸存者空間1使用率(kB)。
TT:任期閥值
MTT:最大任期閥值
DSS:所需的幸存者大小(kB)。
EC:目前eden空間容量(kB)。
EU:Eden空間使用率(kB)。