本文是本人前一段时间做一个简单Java监控工具调研总结,主要包括VisualVm ,JProfiler,Perfino,Yourkit,Perf4J,JProbe,以及对Java微基准测试的简单介绍,总结下来比较推荐,Visualvm,Perfino,yourkit和Jprofiler(推荐值按顺序依次递减),其它工具不太推荐使用。
下面是文章目录结构:
一、VisualVm
1、简介
VisualVM 是一款免费的性能分析工具。它通过 jvmstat、JMX、SA(Serviceability Agent)以及 Attach API 等多种方式从程序运行时获得实时数据,从而进行动态的性能分析。同时,它能自动选择更快更轻量级的技术尽量减少性能分析对应用程序造成的影响,提高性能分析的精度。
2、安装插件并启动VisualVM
打开方式1:Windows环境下输入cmd ==> jvisualvm
打开方式2:Windows环境下Jdk安装目录中C:\Java\jdk1.7.0_15\bin\jvisualvm.exe,双击jvisualvm.exe即可.
从 VisualVM 插件中心安装插件安装步骤 :
- 从主菜单中选择“工具”>“插件”。
- 在“可用插件”标签中,选中该插件的“安装”复选框。单击“安装”。
- 逐步完成插件安装程序。
预览:
3、内存分析
VisualVM 通过检测 JVM 中加载的类和对象信息等帮助我们分析内存使用情况,我们可以通过 VisualVM 的监视标签和 Profiler 标签对应用程序进行内存分析。
在监视标签内,我们可以看到实时的应用程序内存堆以及永久保留区域的使用情况。
Dump在本文中表示转储的意思。
下图是93机器的内存使用情况
堆Dump
装入刚才Dump的文件(200M)
加载后的dump分析:
关于内存分析可以了解:Memory Analyzer Tool(eclispe插件:http://www.eclipse.org/mat/ )
使用 Eclipse Memory Analyzer 进行堆转储文件分析,参考文章:http://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-ma/
4、CPU分析
在监视标签内,我们可以查看 CPU 的使用率以及垃圾回收活动对性能的影响。过高的 CPU 使用率可能是由于我们的项目中存在低效的代码,可以通过 Profiler 标签的 CPU 性能分析功能进行详细的分析。如果垃圾回收活动过于频繁,占用了较高的 CPU 资源,可能是由内存不足或者是新生代和旧生代分配不合理导致的等。
5、线程分析
线程监视情况:
线程分析详细信息:
线程dump图:
关于线程dump:http://blog.csdn.net/gaojava/article/details/12859363
关于visualvm: http://www.ibm.com/developerworks/cn/java/j-lo-visualvm/index.html
6、连接远程tomcat的方法
/opt/apache-tomcat-7.0.42/bin/catalina.sh
#JAVA_OPTS="$JAVA_OPTS -Djava.rmi.server.hostname=172.16.8.82"
#JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8765"
#JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.ssl=false"
#JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.authenticate=false"
JAVA_OPTS="-Djava.rmi.server.hostname=172.16.8.82 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8765 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false";
右键,添加JMX连接,连接远程:
6.1什么是JMX?
JMX(Java Management Extensions,即Java管理扩展)是一个为应用程序、设备、系统等植入管理功能的框架。JMX是一种JAVA的正式规范,它主要目的是让程序有被管理的功能。
二、JProfiler
1、简介
JProfiler是一个全功能的Java剖析工具(profiler),专用于分析J2SE和J2EE应用程序。JProfiler是一个商业授权的Java剖析工具。
2、下载安装
下载地址:http://www.ej-technologies.com/download/jprofiler/files 目前最新版:8.0.7 (2014/07/28)
2.1破解
License key:(来源于网络)
L-Larry_Lau@163.com#23874-hrwpdp1sh1wrn#0620
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
2.3安装插件
2.4配置
Linux环境配置jprofiler
将下载好的jprofiler_linux_8_0_7.sh (http://download-aws.ej-technologies.com/jprofiler/jprofiler_linux_8_0_7.sh)
上传到远程服务器然后进行安装,按默认提示进行安装。
选择端口,默认即可:
上面的配置没有完全成功,但是思路是正确的,可以简单做个参考吧。
三、Perfino
1.简介
Perfino和Jprofiler同属于ej-technologies公司的产品,2014年刚刚推出来,非常新。
2.下载、安装、配置
2.1下载
下载地址:http://www.ej-technologies.com/download/perfino/files
目前最新版本的是1.0。
安装比较简单,一直下一步即可。
2.2配置
需要简单配置一下(目前只有30天的试用期):
可以配置邮件服务器,用来发送监控邮件:
perfino可以监控web项目发出的请求的记录,其用时多久,以及目前CPU的占用,是非常实用的工具,比较推荐!但因为是比较新的工具,目前网上还搜不到多少资料,而且收费也比较高。
四、Yourkit
1、简介
YourKit Java Profiler 是业界领先的Java和.NET的剖析工具。CPU和内存的剖析历来是很困难的,YourKit创造出了革命性的剖析工具,应用在研发和生产阶段,为专业的Java和.NET开发者带来了无比的好处。
2、下载、安装、配置
2.1下载
下载地址:
http://www.yourkit.com/java/profiler/index.jsp
目前最新版:yjp-2013-build-13088
安装:
一直下一步就可以了。
2.2破解
name:
amosli
License-key:
05c970aa7bebced4cda625484241634c28c77b9865448d2f1ae0584df14560b6034a5db93b4425ebc5356fe3730931cd8ac6c09032fd8957f799bf83fa216b735a83086ccf676836087524529b5dad5a72355918bba492b846075b5bc7c2991160343cc001f6063ab833f968127677da0be20da4802d1a450d838c130864b23dfeb44d944b0a78296cffcd6857a320a0b93d324a07de15bde6e9f22c6fc3c2aef2fab0f5f4664808b1f7a4b91e826911612f0d2a278ddf510590e924d5b5aadd21bcdbd24be63d2d5b18d18527ae496daf28f43f45d6ad73c2d19e3cf34e948d6215b483b163aff99cc4897b364ba72049eaaf9e1b7d9f5b0d988e08ceaf53cc15d051e65a0287
破解所需要文件:http://pan.baidu.com/s/1hqFuEcW (破解文件来源网络)
2.3配置
安装ide插件.
插件安装教程:http://www.yourkit.com/docs/yjp2013/help/ide_integration.jsp
Eclipse下的安装教程:http://www.yourkit.com/docs/yjp2013/help/complete_eclipse35.jsp
配置可参考:http://zhwj184.iteye.com/blog/764575
2.demo演示
http://www.yourkit.com/docs/demo/JavaEE/JavaEE.htm
其和Jprofiler非常像!但更建议使用Yourkit,因为配置更简单一点。
五、Jetm
1.简介
JETM是一个Java程序执行时间测量工具,非常轻量级的代码执行时间监控,主要可以记录
WEB项目中发送请求的时间统计等信息以帮助开发人员定位Java程序中的性能问题。
版本记录:
2013/05/12 Good bye sourceforge!
2013/04/01 JETM 1.3.0 on it's way
2009/02/12 Spring bugfix release JETM 1.2.3
2007/07/09 Minor release JETM 1.2.2
2007/05/01 Bugfix release: JETM 1.2.1
Online Demo
http://jetm.void.fm/jetm-demo/
六、Perf4J
1.简介
官网介绍:
Perf4J is to System.currentTimeMillis() as log4j is to System.out.println()
最近的更新时间:Last Published: 2011-10-16
最新版本:0.9.16
2.配置
Maven配置:
<dependency>
<groupId>org.perf4j</groupId>
<artifactId>perf4j</artifactId>
<version>0.9.16</version>
</dependency>
示例:
public static void main(String[] args) throws Exception {
StopWatch stopWatch = new LoggingStopWatch();
long currentTimeMillis = System.currentTimeMillis();
for (int i = 1; i<2000; i++)
{ System.out.println("i:"+i);}
stopWatch.stop("test.class","执行完成dd! ");
System.out.println("time:"+(System.currentTimeMillis()-currentTimeMillis));
}
输出:
i:1996
i:1997
i:1998
i:1999
start[1406469879021] time[44] tag[test.class] message[执行完成dd! ]
time:44
七、JProbe
1.简介
Jprobe主要做Java内存分析,Java线程分析,CPU分析,和JProfiler类似。
2012年7月份Quest公司被DELL以24亿美元收购,2013年Jprobe退出市场。
目前很少有人在用。
八、Java微基准测试
1.示例
protected static int global;
public static void main(String[] args) {
long t1 = System.nanoTime();
int value = 0;
for (int i = 0; i < 100 * 1000 * 1000; i++) {
value = calculate(value);
}
long t2 = System.nanoTime();
System.out.println("Execution time: " + ((t2 - t1) * 1e-6) + " milliseconds");
}
protected static int calculate(int arg) {
// assert (arg >= 0) : "should be positive";//L1
//if (arg < 0) throw new IllegalArgumentException("arg = " + arg + " < 0");//L2
global = arg * 6;
global += 3;
global /= 2;
return arg + 2;
}
选项:
- 保持此代码不变(calculate 中没有 arg 测试)
- 只取消 L1 行的注释标志,但是禁用断言(使用 -disableassertions JVM 选项;这也是默认行为)
- 只取消 L1 行的注释标志,但是启用断言(使用 -enableassertions JVM 选项)
- 只取消 L2 行的注释标志
2002 JavaOne大会结果:
- 5 秒
- 0.2 秒
- (他没有报告这种情况下的数据)
- 5 秒
我的电脑最终的执行结果:
Execution time: 2272.067122 milliseconds //a
Execution time: 2049.659045 milliseconds //b
Execution time: 2053.542801 milliseconds //c
Execution time: 2033.220091 milliseconds//d
Execution time: 2086.269581 milliseconds //放掉L1,L2注释
1.1如何设置断言
boolean isOpen = false;
assert isOpen=true; //如果开启了断言,会将isOpen的值改为true
System.out.println(isOpen);//打印是否开启了断言
// 选择菜单:Run ---> Run... ---> 选择 Arguments 选项卡
// 在 VM arguments 文本框中输入: -ea 注意 中间没有空格,如果输入 -da 表示禁止断言。
// -ea java -ea 打开所有用户类的assertion
// -da java -da 关闭所有用户类的assertion
// -ea:<classname> java -ea:MyClass1 打开MyClass1的assertion
// -da:<classname> java -da: MyClass1 关闭MyClass1的assertion
// -ea:<packagename> java -ea:pkg1 打开pkg1包的assertion
// -da:<packagename> java -da:pkg1 关闭pkg1包的assertion
// -ea:... java -ea:... 打开缺省包(无名包)的assertion
// -da:... java -da:... 关闭缺省包(无名包)的assertion
// -ea:<packagename>... java -ea:pkg1... 打开pkg1包和其子包的assertion
// -da:<packagename>... java -da:pkg1... 关闭pkg1包和其子包的assertion
// -esa java -esa 打开系统类的assertion
// -dsa java -dsa 关闭系统类的assertion
// 综合使用 java -dsa:MyClass1:pkg1 关闭MyClass1和pkg1包的assertion
2.基准测试流程
基准测试通常的过程是:1)记录开始时间,2)执行代码,3)记录结束时间,4)计算时间差。
2.1典型的 Java 基准测试代码
long t1 = System.currentTimeMillis();
task.run(); // task is a Runnable which encapsulates the unit of work
long t2 = System.currentTimeMillis();
System.out.println("My task took " + (t2 - t1) + " milliseconds to execute.");
在真实环境中,System.currentTimeMillis 的分辨率可能会糟糕 10-100 倍。它的 Javadoc 指出:
注意,尽管返回值的时间单位是毫秒,但是值的粒度取决于底层操作系统,甚至可能比操作系统的时间单位更大。例如,许多操作系统以几十毫秒作为时间度量的单位。
已经报告的分辨率数据见表 1:
表 1. 分辨率
分辨率 | 平台 | 来源 |
55 ms | Windows 95/98 | Java Glossary |
10 ms | Windows NT, 2000, XP 单处理器 | Java Glossary |
15.625 ms | Windows XP 多处理器 | Java Glossary |
~15 ms | Windows(可能是指 XP) | Simon Brown |
10 ms | Linux 2.4 内核 | Markus Kobler |
1 ms | Linux 2.6 内核 | Markus Kobler |
所以,对于执行时间小于 10 秒的任务,上面 中的代码很容易出现过大的误差。
3、影响基准测试的因素
Java的执行过程是很复杂的,这其中会有很多因素影响到基准测试。通常来说,Java代码在开始执行阶段会相对很慢,之后会越来越快,直到达到稳定阶段,这一过程涉及的影响因素主要有:
1) 类加载。类加载涉及到文件读取、解析、校验等系列操作,所以在计算真正的task执行前需要先执行几遍task确保类加载都完成了。如果task涉及的条件分支很多,要确保各分支的代码都覆盖到。
及时编译。2) 动态优化。
3) Resource reclamation(资源回收,GC)
4) OS Cache和CPU Cache有时也会影响到基准测试。如果是测试文件IO操作,就不能忽略OS Cache的影响。如果是针对数值做测试,就可能要考虑CPU Cache的影响。
5) 其他因素
6) 硬件的影响,JVM参数的影响等等
4、如何尽可能减小基准测试中不可避免的度量偏差?
- 执行许多次基准测试度量。
- 根据度量值计算出平均值和标准偏差。
- 使用这些统计数据判断是否可以清楚地区分两个任务的速度(平均值之差超过三倍标准偏差),还是相互重叠。
- 计算平均值和标准偏差的置信区间,以此表示这些数据的可靠性。
- 用 bootstrapping 技术计算置信区间是最好的方法。
4.1什么是置信区间?
置信区间并不是统计数据的单一计算值(估值点[point estimate]),而是一个估值范围。与这个范围相关联的概率 p 称为置信水平(confidence level)。在大多数情况下,设 p 为 95%,这个值在置信区间比较期间保持不变。置信区间的意义很直观,因为它们的大小表示可靠性:窄的区间表示统计数据比较精确,宽的区间表示统计数据不太确定。例如,如果任务 A 的平均执行时间的置信区间是 [1, 1.1] 毫秒,任务 B 是 [0.998, 0.999] 毫秒,那么B 的平均值就比 A 可靠性高,还可以确认它的值比 A 小(在置信水平上)。补充资料的 Confidence intervals 一节详细讨论了这个问题。
5.使用框架Benchmark进行基准测试
对计算第 35 个 Fibonacci 数的过程进行基准测试
public static void main(String[] args) throws Exception {
Callable<Integer> task =
new Callable<Integer>() { public Integer call() { return fibonacci(35); } };
System.out.println("fibonacci(35): " + new Benchmark(task));
}
protected static int fibonacci(int n) throws IllegalArgumentException {
if (n < 0) throw new IllegalArgumentException("n = " + n + " < 0");
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
fibonacci(35): first = 305.932 ms, mean = 293.431 ms (CI deltas: -1.202 ms, +1.569 ms), sd = 10.763 ms (CI deltas: -2.332 ms, +3.826 ms) WARNING: execution times have mild outliers, SD VALUES MAY BE INACCURATE
下面解释这些结果:
v 第一次调用 fibonacci(35) 时,执行的时间是 305.932 毫秒。
v 执行时间的平均估值点是 293.431 毫秒。平均值的 95% 置信区间相对于估值点波动 -1.202,+1.569 毫秒,也就是 [292.229, 295] 毫秒。这个区间比较窄,所以这个值是可信的。
v 执行时间的标准偏差估值点是 10.763 ms。标准偏差的 95% 置信区间相对于估值点波动 -2.332 ms, +3.826微秒,也就是 [8.431, 14.589] 毫秒。这个区间相对来说比较宽,所以这个值不太可信。实际上,末尾的警告指出标准偏差度量不准备。
v 结果还指出出现了离群值。在这个示例中,可以不理会这些警告;但是,如果您不放心的话,可以重新运行代码并改用 Benchmark 的toStringFull 方法,这会列出所有统计数据,以便进一步分析。
参考资料:
1. http://www.udpwork.com/item/2383.html
2. http://www.ibm.com/developerworks/cn/java/j-benchmark1.html
3.http://www.ibm.com/developerworks/cn/java/j-benchmark2/
本文中用到的资料分享:http://pan.baidu.com/s/1i3FsVUP (共17.9M)