perf是linux系統中提供的性能分析工具,它基於一個叫「Performance counters」的內核子系統實現,同時支持硬件(CPU、PMU(Performance Monitoring Unit))和軟件(軟件計數器、tracepoint)層面的性能分析。java
perf與其餘性能調優工具同樣,都是經過對監測對象進行採樣,根據採樣點的分佈來推斷整個程序的行爲。經過perf list命令咱們能夠看到perf支持不少的採樣事件,好比branch-misses、cpu-clock等等。perf中預約義的事件屬於不一樣的類型,好比硬件產生的事件(cache 命中/分支miss)和軟件產生的事件(context switch/page fault)等等。linux
tracepoint是linux內核中定義的一些hook,若是被開啓,它們就會在執行到特定邏輯時被觸發,方便其餘工具獲取系統內部的運行狀態等信息,perf就是利用了tracepoint,它會記錄和統計tracepoint的各個事件,生成分析報告。bash
perf 工具的具體使用方式以下:app
perf [--version] [--help] COMMAND [ARGS]
複製代碼
其中的COMMAND列表能夠經過執行perf --help查看,下面列舉幾個經常使用的command。函數
perf stat的做用是執行一個命令並收集其運行過程當中的各個數據,它能夠提供一個程序運行狀況的整體概覽。好比:工具
user@localhost:~$ perf stat hostname
localhost
Performance counter stats for 'hostname':
0.313464 task-clock (msec) # 0.481 CPUs utilized
2 context-switches # 0.006 M/sec
0 cpu-migrations # 0.000 K/sec
153 page-faults # 0.488 M/sec
896,723 cycles # 2.861 GHz
620,709 instructions # 0.69 insn per cycle
121,143 branches # 386.465 M/sec
6,247 branch-misses # 5.16% of all branches
0.000651441 seconds time elapsed
複製代碼
上面這個例子,經過perf stat運行了hostname命令,並將其運行過程當中的一些指標彙總顯示了出來,好比task-clock、context-switches等待。默認狀況下,perf stat 會輸出幾個經常使用的事件的統計,好比:性能
除此以外,咱們可使用-e參數來指定咱們感興趣的事件,好比:ui
user@localhost:~$ perf stat -e cache-misses hostname
localhost
Performance counter stats for 'hostname':
682 cache-misses
0.000646676 seconds time elapsed
複製代碼
perf top的做用是實時地顯示系統當前的性能統計信息。前面的perf stat用於對一個特定的程序進行分析,而某些時候咱們可能並不知道是哪一個程序影響了系統性能,這時候就能夠用perf top來查找可疑的程序。好比:spa
Samples: 775 of event 'cpu-clock', Event count (approx.): 92931021
Overhead Shared Object Symbol
8.93% [kernel] [k] vsnprintf
7.73% perf [.] rb_next
5.92% [kernel] [k] kallsyms_expand_symbol.clone.0
5.07% [kernel] [k] format_decode
4.59% [kernel] [k] number
3.40% perf [.] symbols__insert
3.03% libslang.so.2.2.1 [.] SLtt_smart_puts
複製代碼
上面的例子顯示perf統計了cpu-clock事件的數據,根據比例進行了排序。和perf stat同樣,咱們能夠經過-e參數指定統計其餘的事件,好比perf top -e context-switches能夠查看進程切換最多的top N個進程。code
perf record的做用和perf stat相似,它能夠運行一個命令並生成統計信息,不過perf record不會將結果顯示出來,而是將結果輸出到文件中。perf record生成的文件能夠用perf report來進行解析。
perf record還能夠經過-g參數,在分析時生成calling graph,幫助定位更上層的邏輯分佈。
經過例子咱們能夠發現,perf的分析結果中的Symbol一列顯示的都是c語言函數的名字。對於java來講,jit編譯產生的函數就會直接顯示在symbol裏,而不是java的函數名,這時要定位問題就不是那麼容易了,咱們須要經過額外的手段將symbol和java程序的符號表對應起來,具體後續再討論了。