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

本文通过JProfiler工具深入分析了Java应用中的内存泄漏和线程死锁问题,提供了具体代码示例,并详细解释了如何使用JProfiler进行监控与诊断。内存泄漏示例中,通过测试代码展示了Integer对象内存未被正确释放的情况,通过执行垃圾回收后内存占用量未减少的现象揭示了问题所在。线程死锁示例则展示了两个线程之间的同步冲突,导致线程阻塞的情况。文章旨在帮助开发者理解和解决Java应用中的性能瓶颈。
7451

被折叠的 条评论
为什么被折叠?



