线上服务器内存分析及问题排查
轉載自??線上服務器內存分析及問題排查
平常的工作中,在衡量服務器的性能時,經常會涉及到幾個指標,load、cpu、mem、qps、rt等。每個指標都有其獨特的意義,很多時候在線上出現問題時,往往會伴隨著某些指標的異常。大部分情況下,在問題發生之前,某些指標就會提前有異常顯示。
在第一篇文章中,我們介紹了一個重要的指標就是負載(Load),其中我們提到Linux的負載高,主要是由于CPU使用、內存使用、IO消耗三部分構成。任意一項使用過多,都將導致服務器負載的急劇攀升。本文是該系列的第三篇,來分析一下影響機器負載的幾個原因中的第二項,內存使用。
?
什么是內存
內存是計算機中重要的部件之一,它是與CPU進行溝通的橋梁。計算機中所有程序的運行都是在內存中進行的,因此內存的性能對計算機的影響非常大。
內存(Memory)也被稱為內存儲器,其作用是用于暫時存放CPU中的運算數據,以及與硬盤等外部存儲器交換的數據。
物理內存
物理內存指通過物理內存條而獲得的內存空間。即隨機存取存儲器(random access memory,RAM),是與CPU直接交換數據的內部存儲器,也叫主存(內存)。
虛擬內存
虛擬內存是計算機系統內存管理的一種技術。它使得應用程序認為它擁有連續可用的內存(一個連續完整的地址空間),而實際上,它通常是被分隔成多個物理內存碎片,還有部分暫時存儲在外部磁盤存儲器上,在需要時進行數據交換(也就是說,當物理內存不足時,可能會借用硬盤空間來充當內存使用)。與沒有使用虛擬內存技術的系統相比,使用這種技術的系統使得大型程序的編寫變得更容易,對真正的物理內存(例如RAM)的使用也更有效率。
Swap分區
Swap分區(即交換區)在系統的物理內存不夠用的時候,把硬盤空間中的一部分空間釋放出來,以供當前運行的程序使用。那些被釋放的空間可能來自一些很長時間沒有什么操作的程序,這些被釋放的空間被臨時保存到Swap分區中,等到那些程序要運行時,再從Swap分區中恢復保存的數據到內存中。
程序運行時的數據加載,線程并發,I/O緩沖等等,都依賴于內存,可用內存的大小,決定了程序是否能正常運行以及運行的性能。
查看內存使用情況
在Linux機器上,有多個命令都可以查看機器的內存信息。其中包括free、top等。
free命令
free命令可以顯示Linux系統中空閑的、已用的物理內存,swap分區以及被內核緩沖區內存。在Linux系統監控的工具中,free命令是最經常使用的命令之一。
$freetotal???????used???????free?????shared????buffers?????cached Mem:???????8388608????2926968????5461640??????????0??????????0????1654392 -/+?buffers/cache:????1272576????7116032 Swap:?????16777208??????????0???16777208上圖中,一共有3行6列數據,行數據的意義如下:?Mem 行是內存的使用情況。?-/+ buffers/cache 行是物理內存的緩存統計情況。?Swap 行是交換空間的使用情況。
前面分別介紹過了物理內存和Swap分區。這里再介紹一下buffers和cache。
buffer與cache的區別
A buffer is something that has yet to be "written" to disk.
A cache is something that has been "read" from the disk and stored for later use.
簡單點說:
buffers 就是存放要輸出到disk(塊設備)的數據,緩沖滿了一次寫,提高IO性能(內存 -> 磁盤)
cached 就是存放從disk上讀出的數據,常用的緩存起來,減少IO(磁盤 -> 內存)
buffer 和 cache,兩者都是RAM中的數據。簡單來說,buffer是即將要被寫入磁盤的,cache是被從磁盤中讀出來的。
介紹完了buffer和cache的區別,接下來分析下free命令查詢到的數據。
Mem行
?????????????total???????used???????free?????shared????buffers?????cached Mem:???????8388608????2926968????5461640??????????0??????????0????1654392這一行展示物理內存的整體情況。
Total:8388608。表示物理內存總大小。
Used :2926968。表示總計分配給緩存(包含buffers 與cache )使用的數量,但其中可能部分緩存并未實際使用。
Free :5461640。表示未被分配的內存。
Shared:0。共享內存,一般系統不會用到。
Buffers:0。系統分配但未被使用的buffers 數量。
Cached:1654392。系統分配但未被使用的cache 數量。
total(Mem) = used(Mem) + free(Mem)
-/+ buffers/cache 行
?????????????total???????used???????free?????shared????buffers?????cached -/+?buffers/cache:????1272576????7116032Used:1272576。 表示實際使用的buffers 與cache 總量,也是實際使用的內存總量。
Free:7116032。 未被使用的buffers 與cache 和未被分配的內存之和,這就是系統當前實際可用內存。
used(-/+ buffers/cache) = used(Mem) - cached(Mem) - buffers(Mem)
free(-/+ buffers/cache) = free(Mem) + cached (Mem)+ buffers(Mem)
Swap 行
$freetotal???????used???????free?????shared????buffers?????cached Swap:?????16777208??????????0???16777208Total:16777208。Swap內存總大小。
Used:0。表示已分配的Swap大小。
Free:16777208。表示未被分配的內存。
接下來,再來整體看一下數據。
$freetotal???????used???????free?????shared????buffers?????cached Mem:???????8388608????2926968????5461640??????????0??????????0????1654392 -/+?buffers/cache:????1272576????7116032 Swap:?????16777208??????????0???16777208機器上實際可用內存大小:
???Free(-/+?buffers/cache)=?Free(Mem)+buffers(Mem)+Cached(Mem);7116032?=?5461640?+?0+?1654392已經分配的內存大小:
???Used(Mem)?=?Used(-/+?buffers/cache)+?buffers(Mem)?+?Cached(Mem)2926968?=?1272576?+?0?+?1654392物理內存總大小
???total(Mem)?=?used(-/+?buffers/cache)?+?free(-/+?buffers/cache)8388608?=?1272576?+?7116032總結一下,整個機器的總內存大小8388608,其中已經分配的內存有2926968,還未分配的內存有5461640。而分配的2926968中,有1654392還沒有使用,有1272576已經用掉了。當前機器中還有7116032內存可以使用。
free命令參數
-m?以M為單位顯示內存
$free?-mtotal???????used???????free?????shared????buffers?????cached Mem:??????????8192???????2802???????5389??????????0??????????0???????1559 -/+?buffers/cache:???????1243???????6948 Swap:????????16383??????????0??????16383-g?以G為單位顯示內存
$free?-gtotal???????used???????free?????shared????buffers?????cached Mem:??????????8??????????2??????????5?????????0?????????0???????????1 -/+?buffers/cache:???????1??????????6 Swap:????????16??????????0??????????16-s 2持續的觀察內存的狀況,每隔2秒打印一次
$free?-s?2total???????used???????free?????shared????buffers?????cached Mem:???????8388608????2873128????5515480??????????0??????????0????1600588 -/+?buffers/cache:????1272540????7116068 Swap:?????16777208??????????0???16777208total???????used???????free?????shared????buffers?????cached Mem:???????8388608????2873168????5515440??????????0??????????0????1600628 -/+?buffers/cache:????1272540????7116068 Swap:?????16777208??????????0???16777208除了free ,還可以在Linux下可以使用/proc/meminfo文件查看操作系統內存的使用狀態,其實,free命令的內容也是來自于/proc/meminfo文件。
top命令
top命令是Linux下常用的性能分析工具,能夠實時顯示系統中各個進程的資源占用狀況,類似于Windows的任務管理器。
在前面兩篇文章中介紹過使用top命令查看Load Avg和CPU利用率。top還會打印的一部分信息就是內存情況。
top?-?17:49:32?up?2?days,??6:25,??1?user,??load?average:?0.01,?0.09,?0.12 Tasks:??30?total,???1?running,??29?sleeping,???0?stopped,???0?zombie Cpu(s):??0.1%us,??0.0%sy,??0.0%ni,?88.0%id,??3.8%wa,??0.0%hi,??0.0%si,??8.1%st Mem:???8388608k?total,??2884716k?used,??5503892k?free,????????0k?buffers Swap:?16777208k?total,????????0k?used,?16777208k?free,??1612080k?cachedPID?USER??????PR??NI??VIRT??RES??SHR?S?%CPU?%MEM????TIME+??COMMAND85690?admin?????20???0?5138m?1.1g??47m?S??2.3?13.9??93:28.92?java上面的Mem行和Swap行展示的就是內存的使用情況。并且也會按照進行展示不同進程的內存占用情況。十分好用。
?
Java Web應用內存占用飆高排查思路
JVM以一個進程(Process)的身份運行在Linux系統上,對于Linux來說,JVM不過是一個具有自助管理內存的乖孩子而已。
一般在應用啟動時都可以通過JVM參數來設置JVM內存的大小。如果超過這個限制就會拋出異常。所以,我們比較常見的內存占用過高問題,最顯著的現象就是拋出各種OutOfMemoryError。
有一種可能導致直接內存,也就是Linux的物理內存過高的情況,就是NIO的使用。NIO引入了一種基于通道與緩沖區的IO方式,他可以使用Native函數庫直接分配堆外內存,然后通過一個存儲在Java堆中的DirectByteBuffer對象作為這塊內存的引用進行操作。
所以,在使用NIO的時候,要特別小心,避免導致機器內存被擠滿。
導致JVM中內存占用飆高的原因可能有很多。最常見的就是內存泄露。
內存泄露排查思路
1、使用top命令,查看占用內存較高的進程ID。
???~?topPID?USER??????PR??NI??VIRT??RES??SHR?S?%CPU?%MEM????TIME+??COMMAND 3331?admin?????20???0?7127m?2.6g??38m?S?10.7?90.6??10:20.26?java發現PID為3331的進程占用內存 90.6%。而且是一個Java進程,基本斷定是程序問題。
2、使用jmap查看內存情況,并分析是否存在內存泄露。
jmap?-heap?3331:查看java?堆(heap)使用情況jmap?-histo?3331:查看堆內存(histogram)中的對象數量及大小jmap?-histo:live?3331:JVM會先觸發gc,然后再統計信息jmap?-dump:format=b,file=heapDump?3331:將內存使用的詳細情況輸出到文件得到堆dump文件后,可以進行對象分析。如果有大量對象在持續被引用,并沒有被釋放掉,那就產生了內存泄露,就要結合代碼,把不用的對象釋放掉。
總結
以上是生活随笔為你收集整理的线上服务器内存分析及问题排查的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手机怎么格式化内存卡
- 下一篇: Windows远程桌面不安全Window