Jprofiler监控工具

            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的阻塞的代码位置


猜你喜欢

转载自gemantic.iteye.com/blog/1237277