JProfiler是一款Java的性能监控工具。可以查看当前应用的对象、对象引用、内存、CPU使用情况、线程、线程运行情况(阻塞、等待等),同时可以查找应用内存使用得热点,即:哪个对象占用的内存比较多;或者CPU热点,即:哪儿方法占用的较大得CPU资源等。监控是要消耗系统资源的,所以一般情况下不要用于性能测试时候的监控。
部署启动等相关文档在附件,下面是内存泄漏和线程死锁的例子,JProfiler版本为6.2.4。
- 内存泄漏
1、测试代码
/** * JProfiler内存监控例子 * * @author yhye * @2011-11-9上午09:46:06 */ public class JProfilerMemMain { private Listarr2 = null; // 方法执行完后无法释放Integer的数据内存 public void test2() { arr2 = test(); } // 方法执行完后释放Integer的数据内存 public List test() { List arr = new ArrayList (); 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的调用方的类和方法
查看Thread Views-> Thread Dumps
②线程BB的阻塞的代码位置