日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入浅出JProfiler

發布時間:2025/3/17 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入浅出JProfiler 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

該文章來自阿里巴巴技術協會(ATA

由于最近工作的原因,使用了JProfiler(8)來做性能瓶頸分析,發現這個工具使用起來確實挺方便,現在整理一下JProfiler相關知識(在google查了一通,沒有我想要的)。

一.JProfiler是什么

JProfiler是由ej-technologies GmbH公司開發的一款性能瓶頸分析工具(該公司還開發部署工具)。
其特點:

  • 使用方便
  • 界面操作友好
  • 對被分析的應用影響小
  • CPU,Thread,Memory分析功能尤其強大
  • 支持對jdbc,noSql, jsp, servlet, socket等進行分析
  • 支持多種模式(離線,在線)的分析
  • 跨平臺??(圖1)

二.數據采集

Q1. JProfiler既然是一款性能瓶頸分析工具,這些分析的相關數據來自于哪里?
Q2. JProfiler是怎么將這些數據收集并展現的?


(圖2)

A1. 分析的數據主要來自于下面倆部分
1. 一部分來自于jvm的分析接口**JVMTI**(JVM Tool Interface) , JDK必須>=1.6

JVMTI is an event-based system. The profiling agent library can register handler functions for different events. It can then enable or disable selected events

例如: 對象的生命周期,thread的生命周期等信息
2. 一部分來自于instruments classes(可理解為class的重寫,增加JProfiler相關統計功能)
例如:方法執行時間,次數,方法棧等信息

A2. 數據收集的原理如圖2
1. 用戶在JProfiler GUI中下達監控的指令(一般就是點擊某個按鈕)
2. JProfiler GUI JVM 通過socket(默認端口8849),發送指令給被分析的jvm中的JProfile Agent。
3. JProfiler Agent(如果不清楚Agent請看文章第三部分"啟動模式") 收到指令后,將該指令轉換成相關需要監聽的事件或者指令,來注冊到JVMTI上或者直接讓JVMTI去執行某功能(例如dump jvm內存)
4. JVMTI 根據注冊的事件,來收集當前jvm的相關信息。 例如: 線程的生命周期; jvm的生命周期;classes的生命周期;對象實例的生命周期;堆內存的實時信息等等
5. JProfiler Agent將采集好的信息保存到**內存**中,按照一定規則統計好(如果發送所有數據JProfiler GUI,會對被分析的應用網絡產生比較大的影響)
6. 返回給JProfiler GUI Socket.
7. JProfiler GUI Socket 將收到的信息返回 JProfiler GUI Render
8. JProfiler GUI Render 渲染成最終的展示效果

三. 數據采集方式和啟動模式

A1. JProfier采集方式分為兩種:Sampling(樣本采集)和Instrumentation

  • Sampling: 類似于樣本統計, 每隔一定時間(5ms)將每個線程棧中方法棧中的信息統計出來。優點是對應用影響小(即使你不配置任何Filter, Filter可參考文章第四部分),缺點是一些數據/特性不能提供(例如:方法的調用次數)

  • Instrumentation: 在class加載之前,JProfier把相關功能代碼寫入到需要分析的class中,對正在運行的jvm有一定影響。優點: 功能強大,但如果需要分析的class多,那么對應用影響較大,一般配合Filter一起使用。所以一般JRE class和framework的class是在Filter中通常會過濾掉。

注: JProfiler本身沒有指出數據的采集類型,這里的采集類型是針對方法調用的采集類型 。因為JProfiler的絕大多數核心功能都依賴方法調用采集的數據, 所以可以直接認為是JProfiler的數據采集類型。

A2: 啟動模式:

  • Attach mode
    可直接將本機正在運行的jvm加載JProfiler Agent. 優點是很方便,缺點是一些特性不能支持。如果選擇Instrumentation數據采集方式,那么需要花一些額外時間來重寫需要分析的class。

  • Profile at startup
    在被分析的jvm啟動時,將指定的JProfiler Agent手動加載到該jvm。JProfiler GUI 將收集信息類型和策略等配置信息通過socket發送給JProfiler Agent,收到這些信息后該jvm才會啟動。
    在被分析的jvm 的啟動參數增加下面內容:
    語法: -agentpath:[path to jprofilerti library]
    【注】: 語法不清楚沒關系,JProfiler提供了幫助向導.

    (圖3)

  • Prepare for profiling:
    和Profile at startup的主要區別:被分析的jvm不需要收到JProfiler GUI 的相關配置信息就可以啟動。

  • Offline profiling
    一般用于適用于不能直接調試線上的場景。Offline profiling需要將信息采集內容和策略(一些Trigger, Trigger請參考文章第五部分)打包成一個配置文件(config.xml),在線上啟動該jvm 加載 JProfiler Agent時,加載該xml。那么JProfiler Agent會根據Trigger的類型會生成不同的信息。例如: heap dump; thread dump; method call record等
    語法:
    -agentpath:/home/2080/jprofiler8/bin/linux-x64/libjprofilerti.so=offline,id=151,config=/home/2080/config.xml
    【注】: config.xml中的每一個被分析的jvm的采集信息都有一個id來標識。
    下面是使用了離線模式,并使用了每隔一秒dump heap 的Trigger:

四. JProfiler核心概念

  • Filter: 什么class需要被分析。分為包含和不包含兩種類型的Filter。

    (圖4)

  • Profiling Settings: 收據收集的策略:Sampling和 Instrumentation,一些數據采集細節可以自定義.

    (圖5)

  • Triggers: 一般用于**offline**模式,告知JProfiler Agent 什么時候觸發什么行為來收集指定信息.

    (圖6)

  • Live memory: class/class instance的相關信息。 例如對象的個數,大小,對象創建的方法執行棧,對象創建的熱點。

    (圖7)

  • Heap walker: 對一定時間內收集的內存對像信息進行靜態分析,功能強大且使用。包含對象的outgoing reference, incoming reference, biggest object等

    (圖8)

  • CPU views: CPU消耗的分布及時間(cpu時間或者運行時間); 方法的執行圖; 方法的執行統計(最大,最小,平均運行時間等)

    (圖9)

  • Thread: 當前jvm所有線程的運行狀態,線程持有鎖的狀態,可dump線程。

    (圖10)

  • Monitors & locks: 所有線程持有鎖的情況以及鎖的信息

    (圖11)

  • Telemetries: 包含heap, thread, gc, class等的趨勢圖(遙測視圖)

  • 五. 實踐

    為了方便實踐,直接以JProfiler8自帶的一個例子來幫助理解上面的相關概念。
    JProfiler 自帶的例子如下:模擬了內存泄露和線程阻塞的場景:
    具體源碼參考: /jprofiler install path/demo/bezier


    (圖12 )


    (圖13?Leak Memory?模擬內存泄露,?Simulate blocking?模擬線程間鎖的阻塞)

    A1. 首先來分析下內存泄露的場景:(勾選圖13中 Leak Memory 模擬內存泄露)
    1. 在**Telemetries-> Memory**視圖中你會看到大致如下圖的場景(在看的過程中可以間隔一段時間去執行Run GC這個功能):看到下圖藍色區域,老生代在gc后(**波谷**)內存的大小在慢慢的增加(理想情況下,這個值應該是穩定的)

    (圖14)

  • 在?Live memory->Recorded Objects?中點擊**record allocation data**按鈕,開始統計一段時間內創建的對象信息。執行一次**Run GC**后看看當前對象信息的大小,并點擊工具欄中**Mark Current**按鈕(其實就是給當前對象數量打個標記。執行一次Run GC,然后再繼續觀察;執行一次Run GC,然后再繼續觀察...。最后看看哪些對象在不斷GC后,數量還一直上漲的。最后你看到的信息可能和下圖類似

    (圖15?綠色是標記前的數量,紅色是標記后的增量)

  • 在Heap walker中分析剛才記錄的對象信息

    (圖16)

    (圖17)

  • 點擊上圖中實例最多的class,右鍵**Use Selected Instances->Reference->Incoming Reference**.
    發現該Long數據最終是存放在**bezier.BeaierAnim.leakMap**中。

    (圖18)

  • 在Allocations tab項中,右鍵點擊其中的某個方法,可查看到具體的源碼信息.

    (圖19)

    【注】:到這里問題已經非常清楚了,明白了在圖17中為什么哪些實例的數量是一樣多,并且為什么內存在fullgc后還是回收不了(一個old 區的對象leakMap,put的信息也會進入old區, leakMap如回收不掉,那么該map中包含的對象也回收不掉)。

    A2. 模擬線程阻塞的場景(勾選圖13中Simulate blocking 模擬線程間鎖的阻塞)
    為了方便區分線程,我將Demo中的BezierAnim.java的L236的線程命名為test

    public void start() {thread = new Thread(this, "test");thread.setPriority(Thread.MIN_PRIORITY);thread.start();}

    正常情況下,如下圖

    (圖20)

    勾選了Demo中"Simulate blocking"選項后,如下圖(注意看下下圖中的狀態圖標), test線程block狀態明顯增加了。

    (圖21)

    在**Monitors & locks->Monitor History**觀察了一段時間后,會發現有4種發生鎖的情況。

    第一種:
    AWT-EventQueue-0 線程持有一個Object的鎖,并且處于Waiting狀態。

    圖下方的代碼提示出Demo.block方法調用了object.wait方法。這個還是比較容易理解的。?

    (圖22)

    第二種:
    AWT-EventQueue-0占有了bezier.BezierAnim$Demo實例上的鎖,而test線程等待該線程釋放。

    注意下圖中下方的源代碼, 這種鎖的出現原因是Demo的blcok方法在AWT和test線程
    都會被執行,并且該方法是synchronized.

    (圖23)

    第三種和第四種:
    test線程中會不斷向事件Event Dispatching Thread提交任務,導致競爭java.awt.EventQueue對象鎖。
    提交任務的方式是下面的代碼:repaint()和EventQueue.invokeLater

    public void run() {Thread me = Thread.currentThread();while (thread == me) {repaint();if (block) {block(false);}try {Thread.sleep(10);} catch (Exception e) {break;}EventQueue.invokeLater(new Runnable() {@Overridepublic void run() {onEDTMethod();}});}thread = null;}


    (圖24)

    六. 最佳實踐

  • JProfiler都會對一些特殊操作給予提示,這時候最好仔細閱讀下說明.
  • "Mark Current"功能在某些場景很有效
  • Heap walker一般是靜態分析在Live memory->Recorder objects的對象信息,這些信息可能會被GC回收掉,導致Heap walker中什么也沒有顯示出來。這種現象是正常的。
  • 可以才工具欄中Start Recordings配置一次性收集的信息
  • Filter中include和exclude是有順序的,注意使用下圖**左下方**的**“Show Filter Tree”**來驗證一下順序??(圖25)
  • 七. 參考文獻

  • JProfiler helper:?http://resources.ej-technologies.com/jprofiler/help/doc/index.html
  • JVMTI:?http://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html

    如果上面的描述有錯誤或者不清晰的地方,歡迎斧正。
    另外補充一句:JProfiler是收費的

  • https://oss.aliyuncs.com/yqfiles/84ff55814581391bb8f4248ca9d9264e.ppt

    總結

    以上是生活随笔為你收集整理的深入浅出JProfiler的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。