自己电脑做网站 外网无法访问,做企业网站注意事项,企业网址怎么制作,群晖 建站 Wordpress文章目录 1. 介绍2. 查看堆的变化3. 查看堆快照4. 导出堆快照文件5. 查看class对象加载信息6. CPU分析#xff1a;发现cpu使用率最高的方法7. 查看线程快照#xff1a;发现死锁问题 1. 介绍 VisualVM 是一款免费的#xff0c;集成了多个 JDK 命令行工具的可视化工具#xf… 文章目录 1. 介绍2. 查看堆的变化3. 查看堆快照4. 导出堆快照文件5. 查看class对象加载信息6. CPU分析发现cpu使用率最高的方法7. 查看线程快照发现死锁问题 1. 介绍 VisualVM 是一款免费的集成了多个 JDK 命令行工具的可视化工具它能为您提供强大的分析能力对 Java 应用程序做性能分析和调优。这些功能包括生成和分析海量数据、跟踪内存泄漏、监控垃圾回收器、执行内存和 CPU 分析同时它还支持在 MBeans 上进行浏览和操作。本文主要介绍如何使用 VisualVM 进行性能分析及调优。 用于监控、故障诊断以及性能分析Java应用程序。JVisualVM 通过集成多个命令行JDK工具如 jconsole, jinfo, jmap, jstack 等的功能于一体为用户提供了一个统一且易用的图形界面 位置jdk\bin 作用 查看应用jvm配置信息查看cpu、内存、类、线程监控信息查看堆的变化查看堆快照导出堆快照文件查看class对象加载信息CPU分析发现cpu使用率最高的方法分析死锁问题找到死锁的代码 界面如下 2. 查看堆的变化 每隔3秒堆内存使用新增100M package com.xin.demo.threaddemo.bookdemo;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;public class JVisualVMDemo1 {public static final int _1M 1024 * 1024;public static void main(String[] args) throws InterruptedException {ListObject list new ArrayList();for (int i 0; i 1000; i) {list.add(new byte[100 * _1M]);TimeUnit.SECONDS.sleep(3);System.out.println(i);}}
}查看内存变化 3. 查看堆快照
点击“监视”-”堆(dump)”可以生产堆快照信息. 4. 导出堆快照文件
点击右键另存为 可以用jvisualvm-文件-装入打开hprof文件打开后如下图
5. 查看class对象加载信息
package com.xin.demo.threaddemo.bookdemo;import java.io.File;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;public class JVisualVMDemo2 {private static ListObject insList new ArrayList();public static void main(String[] args) throws Exception {permLeak();}private static void permLeak() throws Exception {for (int i 0; i 2000; i) {URL[] urls getURLS();URLClassLoader urlClassloader new URLClassLoader(urls, null);Class? logfClass Class.forName(org.apache.commons.logging.LogFactory, true, urlClassloader);Method getLog logfClass.getMethod(getLog, String.class);Object result getLog.invoke(logfClass, TestPermGen);insList.add(result);System.out.println(i : result);if (i % 100 0) {TimeUnit.SECONDS.sleep(1);}}}private static URL[] getURLS() throws MalformedURLException {File libDir new File(D:\\javasoft\\apache-maven-3.2.1\\mavenrepository\\commons-logging\\commons-logging\\1.2);File[] subFiles libDir.listFiles();int count subFiles.length;URL[] urls new URL[count];for (int i 0; i count; i) {urls[i] subFiles[i].toURI().toURL();}return urls;}
} 下图可以观察到元空间、类的变化成正相关 6. CPU分析发现cpu使用率最高的方法
CPU 性能分析的主要目的是统计函数的调用情况及执行时间或者更简单的情况就是统计应用程序的 CPU 使用情况。 没有程序运行时的 CPU 使用情况如下图 下面我们写一个cpu占用率比较高的程序。 package com.xin.demo.threaddemo.bookdemo;public class JVisualVMDemo3 {public static void main(String[] args) throws InterruptedException {cpuFix();}/*** cpu 运行固定百分比** throws InterruptedException*/public static void cpuFix() throws InterruptedException {// 80%的占有率int busyTime 8;// 20%的占有率int idelTime 2;// 开始时间long startTime 0;while (true) {// 开始时间startTime System.currentTimeMillis();/** 运行时间*/while (System.currentTimeMillis() - startTime busyTime) {}// 休息时间Thread.sleep(idelTime);}}
} 过高的 CPU 使用率可能是我们的程序代码性能有问题导致的。可以切换到“抽样器”对cpu进行采样可以擦看到那个方法占用的cpu最高然后进行优化。 从图中可以看出cpuFix方法使用cpu最多然后就可以进行响应的优化了。
7. 查看线程快照发现死锁问题
Java 语言能够很好的实现多线程应用程序。当我们对一个多线程应用程序进行调试或者开发后期做性能调优的时候往往需要了解当前程序中所有线程的运行状态是否有死锁、热锁等情况的发生从而分析系统可能存在的问题。
在 VisualVM 的监视标签内我们可以查看当前应用程序中所有活动线程Live threads和守护线程Daemon threads的数量等实时信息。
可以查看线程快照发现系统的死锁问题。 下面我们将通过visualvm来排查一个死锁问题。 package com.xin.demo.threaddemo.bookdemo;public class JVisualVMDemo4 {public static void main(String[] args) {Obj1 obj1 new Obj1();Obj2 obj2 new Obj2();Thread thread1 new Thread(new SynAddRunalbe(obj1, obj2, 1, 2, true));thread1.setName(thread1);thread1.start();Thread thread2 new Thread(new SynAddRunalbe(obj1, obj2, 2, 1, false));thread2.setName(thread2);thread2.start();}/*** 线程死锁等待演示*/public static class SynAddRunalbe implements Runnable {Obj1 obj1;Obj2 obj2;int a, b;boolean flag;public SynAddRunalbe(Obj1 obj1, Obj2 obj2, int a, int b, boolean flag) {this.obj1 obj1;this.obj2 obj2;this.a a;this.b b;this.flag flag;}Overridepublic void run() {try {if (flag) {synchronized (obj1) {Thread.sleep(100);synchronized (obj2) {System.out.println(a b);}}} else {synchronized (obj2) {Thread.sleep(100);synchronized (obj1) {System.out.println(a b);}}}} catch (InterruptedException e) {e.printStackTrace();}}}public static class Obj1 {}public static class Obj2 {}
}程序中thread1持有obj1的锁thread2持有obj2的锁thread1等待获取obj2的锁thread2等待获取obj1的锁相互需要获取的锁都被对方持有者造成了死锁。程序中出现了死锁的情况我们是比较难以发现的。需要依靠工具解决。 打开visualvm查看堆栈信息 点击线程Dump生成线程堆栈信息 上面这段信息可以看出thread1持有Obj1对象的锁等待获取Obj2的锁thread2持有Obj2的锁等待获取Obj1的锁导致了死锁。