async-profiler 分析Java應用CPU和內存分配


一個高性能並且功能比較全面的profiler庫,async-profiler 【Github地址】,可以作為 JProfiler 的開源替代。
async-profiler 提供了 CPU 熱點分析,內存分配采樣分析,鎖分析,時鍾分析,和Java函數(包括JVM native 函數)分析等功能,也提供了分析結果作為火焰圖輸出。

如何讀懂火焰圖參考阮一峰的博客 http://www.ruanyifeng.com/blog/2017/09/flame-graph.html
async-profiler 也提供了比較方便的啟動腳本,比如要采樣分析30s內的CPU熱點

./profiler.sh -e cpu -d 30 pid

使用 list 命令可以查看當前環境支持的分析事件,例如

./profiler.sh list pid

## output
Basic events:
  cpu
  alloc
  lock
  wall
  itimer
Java method calls:
  ClassName.methodName
Perf events:
  page-faults
  context-switches
  cycles
  instructions
  cache-references
  cache-misses
  branch-instructions
  branch-misses
  bus-cycles
  L1-dcache-load-misses
  LLC-load-misses
  dTLB-load-misses
  rNNN
  pmu/event-descriptor/
  mem:breakpoint
  trace:tracepoint
  kprobe:func
  uprobe:path

提供了一個oss的加速地址,
首先進入控制台,下載和解壓 async-profiler

curl -o async-profiler-2.5-linux-x64.tar.gz https://terminus-dice.oss-cn-hangzhou.aliyuncs.com/spot/java-agent/async-profiler/async-profiler-2.5-linux-x64.tar.gz

tar -zxvf async-profiler-2.5-linux-x64.tar.gz && cd async-profiler-2.5-linux-x64

然后 jps 查看 java 的進程 pid

jps

## output
1 app.jar
149 Jps

執行 cpu 熱點分析 ( 示例為進行 30秒的數據采樣,根據實際場景可以調整診斷周期

./profiler.sh -e cpu -d 30 1

## output
Profiling for 30 seconds

...

## ns 表示診斷周期內采樣到的函數執行時間
## percent 表示該函數的占比
## samples 表示函數被采樣到的次數

          ns  percent  samples  top
  ----------  -------  -------  ---
  1170069916    3.55%      115  java_lang_Throwable::fill_in_stack_trace(Handle, methodHandle, Thread*)
  1080180566    3.28%      106  CodeHeap::find_start(void*) const
   979428580    2.97%       97  BacktraceBuilder::push(Method*, int, Thread*)
   820367658    2.49%       70  IndexSetIterator::advance_and_next()
   770204785    2.34%       74  OopMapSet::update_register_map(frame const*, RegisterMap*)
   659625965    2.00%       63  _IO_vfprintf_internal
   600066241    1.82%       59  frame::sender(RegisterMap*) const
   559994122    1.70%       55  PhaseChaitin::Split(unsigned int, ResourceArea*)
   500089045    1.52%       48  java.util.regex.Pattern$Slice.match
   470039625    1.43%       45  vframeArray::allocate(JavaThread*, int, GrowableArray<compiledVFrame*>*, RegisterMap*, frame, frame, frame, bool)
   430450575    1.31%       41  _int_malloc
   409666771    1.24%       40  sun.net.www.ParseUtil.encodePath
   400089494    1.21%       39  resource_allocate_bytes(unsigned long, AllocFailStrategy::AllocFailEnum)
   380146025    1.15%       37  pthread_getspecific
   371189901    1.13%       36  PhaseChaitin::interfere_with_live(unsigned int, IndexSet*)
   360380475    1.09%       32  Deoptimization::fetch_unroll_info_helper(JavaThread*)
   360090466    1.09%       35  jshort_disjoint_arraycopy
   310034456    0.94%       31  RegisterMap::RegisterMap(RegisterMap const*)
   280047136    0.85%       27  org.springframework.boot.loader.jar.JarFileEntries.getEntry
   280007669    0.85%       28  CodeCache::find_blob(void*)
   270352542    0.82%       27  _int_free
   270065077    0.82%       26  nmethod::is_zombie() const
   260038542    0.79%       25  __libc_malloc

執行內存分配分析 ( 示例為進行 30秒的數據采樣,根據實際場景可以調整診斷周期

./profiler.sh -e alloc -d 30 1

# output 
Profiling for 30 seconds

...

## bytes 表示診斷周期內該類型觸發分配的總字節數
## percent 表示診斷周期內該類型觸發分配的總字節數占診斷周期內JVM分配總內存的比例
## samples 表示該類型被采樣到次數

     bytes  percent  samples  top
  ----------  -------  -------  ---
    31107144   51.79%      171  char[]
     5745504    9.57%       16  java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
     4189704    6.98%        9  int[]
     3390448    5.65%       47  byte[]
     3234784    5.39%       11  java.lang.String
     1518048    2.53%        4  org.dozer.event.DozerEvent
     1497888    2.49%        6  java.util.ArrayList$Itr
     1319992    2.20%        6  java.util.HashMap$Node
      922816    1.54%        1  java.util.regex.Pattern$Slice
      890656    1.48%        3  java.lang.StringBuilder
      759208    1.26%        2  java.lang.Object[]
      618472    1.03%        1  org.springframework.boot.loader.jar.JarURLConnection
      383064    0.64%        1  java.lang.String[]
      379536    0.63%        1  org.springframework.asm.Label
      379528    0.63%        1  org.springframework.asm.Item
      379520    0.63%        1  java.nio.HeapCharBuffer
      379520    0.63%        1  java.nio.HeapByteBuffer
      379504    0.63%        1  java.util.LinkedList
      379496    0.63%        1  java.util.LinkedList$Node
      379496    0.63%        1  org.springframework.boot.loader.jar.JarURLConnection$JarEntryName
      379496    0.63%        1  java.lang.Class[]

使用 -f profiler.html 參數輸出火焰圖,比如

./profiler.sh -e cpu -d 30 -f profiler.html 1

在容器內生成火焰圖文件

火焰圖打開效果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM