JProfiler是一款Java的性能监控工具。可以查看当前应用的对象、对象引用、内存、CPU使用情况、线程、线程运行情况(阻塞、等待等),同时可以查找应用内存使用得热点,即:哪个对象占用的内存比较多;或者CPU热点,即:哪儿方法占用的较大得CPU资源等。监控是要消耗系统资源的,所以一般情况下不要用于性能测试时候的监控。
部署启动等相关文档在附件,下面是内存泄漏和线程死锁的例子,JProfiler版本为6.2.4。
- 内存泄漏
1、测试代码
/**
* JProfiler内存监控例子
*
* @author yhye
* @2011-11-9上午09:46:06
*/
public class JProfilerMemMain {
private List<Integer> arr2 = null;
// 方法执行完后无法释放Integer的数据内存
public void test2() {
arr2 = test();
}
// 方法执行完后释放Integer的数据内存
public List<Integer> test() {
List<Integer> arr = new ArrayList<Integer>();
for (int i = 0; i < 200000; i++) {
arr.add(i * 100);
}
return arr;
}
public static void main(String[] args) throws IOException {
JProfilerMemMain jp = new JProfilerMemMain();
for (int i = 1; i <= 10; i++) {
jp.test2();
// jp.test();
}
System.out.println("程序执行完毕");
// 以下方法为保持程序处于活动状态
char ch = ' ';
while (ch != 'n') {
ch = ch;
}
}
2、查看步骤
启动JProfiler,等程序打印出"程序执行完毕" 后查看如下,Integer对象有800264个
点击菜单上的按钮"Run GC" 执行垃圾回收后查看如下,Integer对象还有200270个
说明未完全释放数据,查看对象在堆的快照
从以下视图可以看到该对象的arr2属性有数据未释放
①Heap Walker->Biggest Objects
②Heap Walker->References,JProfilerMemMain对象自身占用空间16bytes,引用其他对象占空间4288kB
③Heap Walker->Data,中arr2属性有数据占用空间
- 死锁
1、测试代码
package com.yyh.base.jprofile;
/**
* 死锁例子
* @author yhye
* @2011-11-8上午09:12:25
*/
public class DeadlockMain implements Runnable {
boolean flag;
static Object o1 = new Object();
static Object o2 = new Object();
public void run() {
System.out.println(flag);
if (flag) {
synchronized (o1) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o2) {
System.out.println("AAA");
}
}
} else {
synchronized (o2) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o1) {
System.out.println("BBB");
}
}
}
}
public static void main(String[] args) {
DeadlockMain aaa = new DeadlockMain();
DeadlockMain bbb = new DeadlockMain();
aaa.flag = true;
bbb.flag = false;
Thread thA = new Thread(aaa);
thA.setName("线程AAA");
Thread thB = new Thread(bbb);
thB.setName("线程BB");
thA.start();
thB.start();
}
}
2、查看步骤
启动JProfiler,等程序执行一段时间后查看如下,线程AAA和线程BB出现阻塞
查看Thread Views-> Thread Monitor
①线程AAA的调用方的类和方法
②线程BB的调用方的类和方法
查看Thread Views-> Thread Dumps
①线程AAA的阻塞的代码位置
②线程BB的阻塞的代码位置