前段时间在给公司项目做性能分析,从简单的分析Log(GC log, postgrep log, hibernate statitistic),到通过AOP搜集软件运行数据,再到PET测试,感觉时间花了不少,性能也有一定的提升,但总感觉像是工作在原始时代,无法简单顺畅,又无比清晰的获得想要的结果。遂花费了一定的时间,从新梳理学习了一下之前用过的关于jvm调优和内存分析的各种工具,包括JDK自带的jps, jstack, jmap, jconsole,以及IBM的HeapAnalyzer等,这些工具虽然提供了不少功能,但其可用度,便捷度,远没达到IntelliJ之于Java开发那种地步。在偶然情况下,在云栖社区上发现有人推荐Jprofiler,装上使用版一用,发现果然是神器,特此推荐给大家。先声明,这个软件是商用的,网上有很多关于lisence的帖子,我这里转发,但是绝不推荐大家用破解版!

L-Larry_Lau@163.com#36573-fdkscp15axjj6#25257
L-Larry_Lau@163.com#5481-ucjn4a16rvd98#6038
L-Larry_Lau@163.com#99016-hli5ay1ylizjj#27215
L-Larry_Lau@163.com#40775-3wle0g1uin5c1#0674
L-Larry_Lau@163.com#7009-14frku31ynzpfr#20176
L-Larry_Lau@163.com#49604-1jfe58we9gyb6#5814
L-Larry_Lau@163.com#25531-1qcev4yintqkj#23927
L-Larry_Lau@163.com#96496-1qsu1lb1jz7g8w#23479
L-Larry_Lau@163.com#20948-11amlvg181cw0p#171159

然后,先转一篇云栖上的文章,然后再慢慢开始我们的Jprofiler之旅。

一.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核心概念

  1. Filter: 什么class需要被分析。分为包含和不包含两种类型的Filter。

    (图4)

  2. Profiling Settings: 收据收集的策略:Sampling和 Instrumentation,一些数据采集细节可以自定义.

    (图5)

  3. Triggers: 一般用于**offline**模式,告知JProfiler Agent 什么时候触发什么行为来收集指定信息.

    (图6)

  4. Live memory: class/class instance的相关信息。 例如对象的个数,大小,对象创建的方法执行栈,对象创建的热点。

    (图7)

  5. Heap walker: 对一定时间内收集的内存对像信息进行静态分析,功能强大且使用。包含对象的outgoing reference, incoming reference, biggest object等

    (图8)

  6. CPU views: CPU消耗的分布及时间(cpu时间或者运行时间); 方法的执行图; 方法的执行统计(最大,最小,平均运行时间等)

    (图9)

  7. Thread: 当前jvm所有线程的运行状态,线程持有锁的状态,可dump线程。

    (图10)

  8. Monitors & locks: 所有线程持有锁的情况以及锁的信息

    (图11)

  9. 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)

  1. 在 Live memory->Recorded Objects 中点击**record allocation data**按钮,开始统计一段时间内创建的对象信息。执行一次**Run GC**后看看当前对象信息的大小,并点击工具栏中**Mark Current**按钮(其实就是给当前对象数量打个标记。执行一次Run GC,然后再继续观察;执行一次Run GC,然后再继续观察...。最后看看哪些对象在不断GC后,数量还一直上涨的。最后你看到的信息可能和下图类似

    (图15 绿色是标记前的数量,红色是标记后的增量)

  2. 在Heap walker中分析刚才记录的对象信息

    (图16)

    (图17)

  3. 点击上图中实例最多的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)

六. 最佳实践

  1. JProfiler都会对一些特殊操作给予提示,这时候最好仔细阅读下说明.
  2. "Mark Current"功能在某些场景很有效
  3. Heap walker一般是静态分析在Live memory->Recorder objects的对象信息,这些信息可能会被GC回收掉,导致Heap walker中什么也没有显示出来。这种现象是正常的。
  4. 可以才工具栏中Start Recordings配置一次性收集的信息
  5. Filter中include和exclude是有顺序的,注意使用下图**左下方**的**“Show Filter Tree”**来验证一下顺序  (图25)

七. 参考文献

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

转自:https://www.cnblogs.com/shenwen/p/11213256.html

jprofiler 监听远程java项目

1、下载、安装windows和linux版的jprofile.注意:若监控的是springboot、springcloud项目,切记本地和服务器上的jprofile要版本保持一致,本人亲自踩过坑。

官网下载地址:http://www.ej-technologies.com/download/jprofiler/files

2、具体安装细节可参考我的jprofile官方文档,甚是详细。

jprofile官方文档在我百度网盘,可凭链接、提取码获取:

链接:https://pan.baidu.com/s/1C1ETpfz75nsx1rs-HHSA7A

提取码:q4l2

3、linux安装完成之后,在jprofile9目录打开bin目录,运行./jpenable文件;此时会把java相关的所有进程列出来,让你选择需要监视的进程jvm的运行情况,选择好之后最后填写对外网能访问的端口,即可在客户端(windows)打开jprofiler进行监视链接就可以用了(端口要保持一样,并不是默认的端口8849,而是自己之前填写对外网可以访问的端口)。

4、既然指定端口为8084,那么本地的端口就需要填写这个。如下:

5、如何关闭JProfiler 监控?

只有一种方式:重启被监控的进程,JProfiler 自动关闭。

6、好了,已经成功了。

JProfiler安装使用教程详解 侵删相关推荐

  1. mysql-win安装教程,WINDOWS下安装MYSQL教程详解

    1.下载安装包 2.配置环境变量 2.1 解压所下载的压缩包 2.2 环境变量 win 10 电脑 这么进去 3.生成data文件 在你解压的目录下,eg:F:\Program Files\mysql ...

  2. mysql 5.6.31 配置_MySQL5.6.31 winx64.zip 安装配置教程详解

    #1. 下载 # #2.解压到本地 修改必要配置my*.ini #3.mysql install admin模式启动cmd cd mysql目录/bin 执行安装: mysqld -install 启 ...

  3. zip安装mysql没有软件,windows10系统安装mysql-8.0.13(zip安装) 的教程详解

    安装环境说明 解压安装包 •解压路径:D:\develop\software •解压后mysql根目录:D:\develop\software\mysql-8.0.13-winx64 原则: 安装目录 ...

  4. Android模拟器Genymotion安装使用教程详解

    原文地址为: Android模拟器Genymotion安装使用教程详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.注册\登录 打开Genymotion官网,https://www.ge ...

  5. mysql binlog2sql_mysql闪回工具binlog2sql安装配置教程详解

    概述 binlog2sql是一个Python开发开源的MySQL Binlog解析工具,能够将Binlog解析为原始的SQL,也支持将Binlog解析为回滚的SQL,去除主键的INSERT SQL,是 ...

  6. 新版mysql的下载教程_Mysql最新版8.0.21下载安装配置教程详解

    一.下载 1.下载安装包 mysql下载路径:https://dev.mysql.com/downloads/file/?id=496745 2.解压压缩包 解压到安装的目录: 3.在此目录下新建my ...

  7. ABBYY FineReader非15版16版注册机序列号秘钥下载版,安装使用教程详解

    OCR文字识别软件abbyy15安装使用教程: 介绍:ABBYY FineReader 15 是一款优秀的OCR图片文字识别软件.它可以从图片上识别文件或表格,识别率非常高,批处理识别功能等,使用AB ...

  8. python qtdesigner安装,PyCharm+Qt Designer+PyUIC安装配置教程详解

    Qt Designer用于像VC++的MFC一样拖放.设计控件 PyUIC用于将Qt Designer生成的.ui文件转换成.py文件 Qt Designer和PyUIC都包含在PyQt5中,所以我们 ...

  9. mysql 5.7 window x64_window环境配置Mysql 5.7.21 windowx64.zip免安装版教程详解

    1.从官网下载mysql-5.7.21-windowx64.zip mysql下载页面 2.解压到合适的位置(E:mysql) 这名字是我改过的 3.配置环境变量,将E:mysqlbin 添加到PAT ...

最新文章

  1. oracle引号的嵌套,3.4.2 在一个直接量字符串中嵌入单引号
  2. xshell 图形化连接ubuntu
  3. mysql repalication_mysql replication(主从复制)(一)MS模式
  4. swoole 异步系统文件IO
  5. 信息学奥赛一本通 1172:求10000以内n的阶乘 | OpenJudge NOI 1.6 14:求10000以内n的阶乘
  6. mysql exporter_mysql exporter
  7. linux stat 命令查看文件信息
  8. WWDC心愿单:新版OS X或将有这些变化
  9. jq22扒的网站, 左右箭头图标问题
  10. 一颗电阻失效引发的设计思考
  11. Linux系统中的用户管理
  12. 在oracle中插入语句要求,oracle插入语句
  13. 国内常见的日内CTA策略介绍以及实现
  14. SQL摘录笔记 --分组数据(5)
  15. maximo开发经验
  16. Win10+Vmvare+Ubuntu16.04lts的主机为英伟达TX2重装Ubuntu18.04操作系统
  17. 男人应享有动听词汇的权利
  18. 深度学习基础:评价标准——TP、FN、FP、TN、AP、MAP
  19. golang学习笔记(十六):多态的实现
  20. 如何用C语言实现小游戏——扫雷

热门文章

  1. 千聊 m8u文件读取下载视频
  2. 钟丽缇胯也太宽了吧,抹胸裙都快撑破了, 张伦硕能hold住么
  3. 技术面试老是有劲使不出,该怎么办? 1
  4. unity全免费下载网站 源代码插件模型场景全部免费
  5. 【开发工具】AR原型的浏览器扩展
  6. 乔春洋:一个具有划时代意义的概念:品牌定位
  7. 弟中弟的Leetcode总结——数组类(六)
  8. opengl绘制三次hermite曲线,三次cardinal曲线
  9. 计算机无法启动windows无线连接,windows无法启动wlan autoconfig服务 窗口无法启动无线配置...
  10. Solr suggest配置