前言:java
性能優化是一個老生常談的話題,典型的性能問題如頁面響應慢、接口超時,服務器負載高、併發數低,數據庫頻繁死鎖等。尤爲是在「糙快猛」的互聯網開發linux
模式大行其道的今天,隨着系統訪問量的日益增長和代碼的臃腫,各類性能問題開始紛至沓來。nginx
在系統層面可以影響應用性能的通常包括三個因素:CPU、內存和IO,今天,咱們先談談CPU性能的監控以及調優。shell
當程序響應變慢的時候,首先使用top、vmstat、ps等命令查看系統的cpu使用率是否有異常,從而能夠判斷出是不是cpu繁忙形成的性能問題。數據庫
其中,主要經過us(用戶進程所佔的%)這個數據來看異常的進程信息。當us接近100%甚至更高時,能夠肯定是cpu繁忙形成的響應緩慢。通常說來,cpu繁忙性能優化
的緣由有如下幾個:服務器
top命令多線程
對於多個或多核cpu,上面的顯示則會是多個cpu所佔用的百分比總合。如需查看每一個核的消耗狀況,可在進入top視圖後按1,就會按核來顯示cpu的使用狀況,併發
如上圖。函數
us 表示用戶進程處理所佔的百分比sy 表示爲內核線程處理所佔的百分比ni 表示被nice命令改變優先級的任務所佔的百分比id 表示cpu的空閒時間所佔的百
分比wa 表示爲在執行過程當中等待io所佔的百分比hi 表示爲硬件中斷所佔的百分比si 表示爲軟件中斷所佔的百分比st 表示虛擬cpu等待實際cpu的時間的百
分比
vmstat命令
in 每秒CPU的中斷次數,包括時間中斷cs 每秒上下文切換次數,這個值要越小越好,太大了,要考慮調低線程或者進程的數目。每次調用系統函數,咱們
的代碼就會進入內核空間,致使上下文切換,這個是很耗資源,也要儘可能避免頻繁調用系統函數。上下文切換次數過多表示你的CPU大部分浪費在上下文切
換,致使CPU幹正經事的時間少了,CPU沒有充分利用,是不可取的。us 用戶CPU時間。sy 系統CPU時間,若是過高,表示系統調用時間長,例如是IO操
做頻繁。id 空閒 CPU時間,通常來講,id + us + sy = 100,通常我認爲id是空閒CPU使用率,us是用戶CPU使用率,sy是系統CPU使用率。wt 等待IO
CPU時間。
若是發現是Java進程CPU佔用太高,可使用這個命令查看進程是否是正在頻繁GC,以下圖所示。
前言:
性能優化是一個老生常談的話題,典型的性能問題如頁面響應慢、接口超時,服務器負載高、併發數低,數據庫頻繁死鎖等。尤爲是在「糙快猛」的互聯網開發
模式大行其道的今天,隨着系統訪問量的日益增長和代碼的臃腫,各類性能問題開始紛至沓來。
在系統層面可以影響應用性能的通常包括三個因素:CPU、內存和IO,今天,咱們先談談CPU性能的監控以及調優。
當程序響應變慢的時候,首先使用top、vmstat、ps等命令查看系統的cpu使用率是否有異常,從而能夠判斷出是不是cpu繁忙形成的性能問題。
其中,主要經過us(用戶進程所佔的%)這個數據來看異常的進程信息。當us接近100%甚至更高時,能夠肯定是cpu繁忙形成的響應緩慢。通常說來,cpu繁忙
的緣由有如下幾個:
top命令
對於多個或多核cpu,上面的顯示則會是多個cpu所佔用的百分比總合。如需查看每一個核的消耗狀況,可在進入top視圖後按1,就會按核來顯示cpu的使用狀況,
如上圖。
us 表示用戶進程處理所佔的百分比sy 表示爲內核線程處理所佔的百分比ni 表示被nice命令改變優先級的任務所佔的百分比id 表示cpu的空閒時間所佔的百
分比wa 表示爲在執行過程當中等待io所佔的百分比hi 表示爲硬件中斷所佔的百分比si 表示爲軟件中斷所佔的百分比st 表示虛擬cpu等待實際cpu的時間的百
分比
vmstat命令
in 每秒CPU的中斷次數,包括時間中斷cs 每秒上下文切換次數,這個值要越小越好,太大了,要考慮調低線程或者進程的數目。每次調用系統函數,咱們
的代碼就會進入內核空間,致使上下文切換,這個是很耗資源,也要儘可能避免頻繁調用系統函數。上下文切換次數過多表示你的CPU大部分浪費在上下文切
換,致使CPU幹正經事的時間少了,CPU沒有充分利用,是不可取的。us 用戶CPU時間。sy 系統CPU時間,若是過高,表示系統調用時間長,例如是IO操
做頻繁。id 空閒 CPU時間,通常來講,id + us + sy = 100,通常我認爲id是空閒CPU使用率,us是用戶CPU使用率,sy是系統CPU使用率。wt 等待IO
CPU時間。
若是發現是Java進程CPU佔用太高,可使用這個命令查看進程是否是正在頻繁GC,以下圖所示。
jstat命令
S0 — Heap上的 Survivor space 0 區已使用空間的百分比S1 — Heap上的 Survivor space 1 區已使用空間的百分比E — Heap上的 Eden space 區已使用
空間的百分比O — Heap上的 Old space 區已使用空間的百分比P — Perm space 區已使用空間的百分比YGC — 從應用程序啓動到採樣時發生 Young GC
的次數YGCT– 從應用程序啓動到採樣時 Young GC 所用的時間(單位秒)FGC — 從應用程序啓動到採樣時發生 Full GC 的次數FGCT– 從應用程序啓動到採
樣時 Full GC 所用的時間(單位秒)GCT — 從應用程序啓動到採樣時用於垃圾回收的總時間(單位秒)
根據上面提供的幾個經常使用命令,定位到問題之後,就能夠根據具體問題分析其產生的緣由了。
CPU瓶頸表如今兩個方面:用戶態CPU瓶頸和系統態CPU瓶頸。運行操做系統內核之外的軟件時致使的瓶頸爲用戶態CPU瓶頸,運行操做系統內核的時候導
致的瓶頸爲系統態CPU瓶頸。用戶態CPU和系統態CPU時間比率在3:1到4:1之間是正常的。若是在有瓶頸的系統中,用戶和系統時間比率高於這個區間,就
應該分析用戶態CPU時間增長的緣由。
當us值太高時,表示運行的應用消耗了大部分的cpu。在這種狀況下,對於java應用而言,最重要的是找到具體消耗cpu的線程所執行的代碼,能夠採用以下方
法。
1.使用gstat -gcutil查看JVM是否頻繁的進行GC。2.若是根據gcutil查看,GC並不頻繁,請根據《當CPU飆高時,它在作什麼》提供的方式,查看CPU在執
行什麼代碼,來定位問題。
當sy值太高時,使用vmstat來查看線程切換次數。極可能是linux花費了更多的時間在進行線程切換。java應用形成這種現象的主要緣由是啓動的線程比較多,
且這些線程多處於不斷的阻塞(例如鎖等待,io等待)和執行狀態的變化過程當中,這就致使了操做系統要不斷的切換執行的線程, 產生大量的上下文切換。
在這種狀況下,對java應用而言,最重要的是找出不斷切換狀態的緣由, 可採用的方法爲經過kill -3 pid 或jstack -l pid的方法dump出java應用程序的線程信
息,查看線程的狀態信息以及鎖信息, 找出等待狀態或鎖競爭過多的線程。
可使用nice和renice設置程序執行的優先級。
格式:nice [-n 數值] 命令nice 指令能夠改變程序執行的優先權等級。指令讓使用者在執行程序時,指定一個優先等級,稱之爲 nice 值。 這個數值從最高優先級
的-20到最低優先級的19。
負數值只有 root 纔有權力使。 通常使用者,也可以使用 nice 指令來作執行程序的優先級管理,但只能將nice值越調越高。
注意,ulimit 限制的是當前shell進程以及其派生的子進程。所以能夠在腳本中調用ulimit來限制cpu使用時間。 例如,限制tar的cpu佔用時間,單位秒。
若是tar佔用時間超過了100秒,tar將會退出,這可能會致使打包不徹底,所以不推薦使用ulimit對cpu佔用時間進行限制。 另外,經過修改系統
的/etc/security/limits配置文件,能夠針對用戶進行限制。
某些程序自帶了對cpu使用調整的功能,好比nginx服務器,經過其配置文件,能夠爲工做進程指定cpu,以下:
這裏0001 0010 0100 1000是掩碼,分別表明第一、二、三、4顆cpu核心,這就使得cpu的使用比較平均到每一個核心上。
使用Nginx時,這種優化方式是比較常見的。
jstat命令
S0 — Heap上的 Survivor space 0 區已使用空間的百分比S1 — Heap上的 Survivor space 1 區已使用空間的百分比E — Heap上的 Eden space 區已使用
空間的百分比O — Heap上的 Old space 區已使用空間的百分比P — Perm space 區已使用空間的百分比YGC — 從應用程序啓動到採樣時發生 Young GC
的次數YGCT– 從應用程序啓動到採樣時 Young GC 所用的時間(單位秒)FGC — 從應用程序啓動到採樣時發生 Full GC 的次數FGCT– 從應用程序啓動到採
樣時 Full GC 所用的時間(單位秒)GCT — 從應用程序啓動到採樣時用於垃圾回收的總時間(單位秒)
根據上面提供的幾個經常使用命令,定位到問題之後,就能夠根據具體問題分析其產生的緣由了。
CPU瓶頸表如今兩個方面:用戶態CPU瓶頸和系統態CPU瓶頸。運行操做系統內核之外的軟件時致使的瓶頸爲用戶態CPU瓶頸,運行操做系統內核的時候導
致的瓶頸爲系統態CPU瓶頸。用戶態CPU和系統態CPU時間比率在3:1到4:1之間是正常的。若是在有瓶頸的系統中,用戶和系統時間比率高於這個區間,就
應該分析用戶態CPU時間增長的緣由。
當us值太高時,表示運行的應用消耗了大部分的cpu。在這種狀況下,對於java應用而言,最重要的是找到具體消耗cpu的線程所執行的代碼,能夠採用以下方
法。
1.使用gstat -gcutil查看JVM是否頻繁的進行GC。2.若是根據gcutil查看,GC並不頻繁,請根據《當CPU飆高時,它在作什麼》提供的方式,查看CPU在執
行什麼代碼,來定位問題。
當sy值太高時,使用vmstat來查看線程切換次數。極可能是linux花費了更多的時間在進行線程切換。java應用形成這種現象的主要緣由是啓動的線程比較多,
且這些線程多處於不斷的阻塞(例如鎖等待,io等待)和執行狀態的變化過程當中,這就致使了操做系統要不斷的切換執行的線程, 產生大量的上下文切換。
在這種狀況下,對java應用而言,最重要的是找出不斷切換狀態的緣由, 可採用的方法爲經過kill -3 pid 或jstack -l pid的方法dump出java應用程序的線程信
息,查看線程的狀態信息以及鎖信息, 找出等待狀態或鎖競爭過多的線程。
可使用nice和renice設置程序執行的優先級。
格式:nice [-n 數值] 命令nice 指令能夠改變程序執行的優先權等級。指令讓使用者在執行程序時,指定一個優先等級,稱之爲 nice 值。 這個數值從最高優先級
的-20到最低優先級的19。
負數值只有 root 纔有權力使。 通常使用者,也可以使用 nice 指令來作執行程序的優先級管理,但只能將nice值越調越高。
注意,ulimit 限制的是當前shell進程以及其派生的子進程。所以能夠在腳本中調用ulimit來限制cpu使用時間。 例如,限制tar的cpu佔用時間,單位秒。
若是tar佔用時間超過了100秒,tar將會退出,這可能會致使打包不徹底,所以不推薦使用ulimit對cpu佔用時間進行限制。 另外,經過修改系統
的/etc/security/limits配置文件,能夠針對用戶進行限制。
某些程序自帶了對cpu使用調整的功能,好比nginx服務器,經過其配置文件,能夠爲工做進程指定cpu,以下:
這裏0001 0010 0100 1000是掩碼,分別表明第一、二、三、4顆cpu核心,這就使得cpu的使用比較平均到每一個核心上。
使用Nginx時,這種優化方式是比較常見的。