财政局网站开发合同,国外的网站用不用备案,Wordpress怎么做导航页,响应式网站的服务jvisualvm多合一故障处理工具
1、visualvm介绍
VisualVM是一款免费的#xff0c;集成了多个 JDK 命令行工具的可视化工具#xff0c;它能为您提供强大的分析能力#xff0c;对 Java 应
用程序做性能分析和调优。这些功能包括生成和分析海量数据、跟踪内存泄漏、监控垃圾回…jvisualvm多合一故障处理工具
1、visualvm介绍
VisualVM是一款免费的集成了多个 JDK 命令行工具的可视化工具它能为您提供强大的分析能力对 Java 应
用程序做性能分析和调优。这些功能包括生成和分析海量数据、跟踪内存泄漏、监控垃圾回收器、执行内存和
CPU 分析同时它还支持在 MBeans 上进行浏览和操作。
本文主要介绍如何使用 VisualVM 进行性能分析及调优。
VisualVM位于{JAVA_HOME}/bin目录中。
在linux和windows下通过jvisualvm启动。 下面我们来看visualvm的各种功能。
2、查看jvm配置信息
第一步点击左边窗口显示正在运行的java进程 第二步点击右侧窗口概述可以查看各种配置信息 通过jdk提供的jinfo命令工具也可以查看上面的信息。 3、查看cpu、内存、类、线程监控信息 4、查看堆的变化
步骤一运行下面的代码
每隔3秒堆内存使用新增100M。
package com.example.controller;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;public class Demo4 {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);}}
}步骤二在VisualVM可以很清晰的看到堆内存变化信息。 4、查看堆快照
步骤一点击监视-堆(dump)可以生产堆快照信息. 生成了以heapdump开头的一个选项卡内容如下 对于堆 dump来说在远程监控jvm的时候VisualVM是没有这个功能的只有本地监控的时候才有。
5、导出堆快照文件
步骤一查看堆快照此步骤可以参考上面的查看堆快照功能
步骤二右键点击另存为即可导出hprof堆快照文件可以发给其他同事分析使用 6、查看class对象加载信息
这次来看下永久保留区域PermGen使用情况。
步骤一运行一段类加载的程序。
package com.example.controller;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 Demo5 {private static ListObject insList new ArrayListObject();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(C:\\zsxsoftware\\apache-maven-3.3.9-bin\\repository\\commons-logging\\commons-logging\\1.1.1);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;}
}步骤二打开visualvm查看metaspace。 7、CPU分析发现cpu使用率最高的方法
CPU 性能分析的主要目的是统计函数的调用情况及执行时间或者更简单的情况就是统计应用程序的 CPU 使用情
况。没有程序运行时的 CPU 使用情况如下图 下面我们写一个cpu占用率比较高的程序。
步骤一运行下列程序。
package com.example.controller;public class Demo6 {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);}}
}步骤二打开visualvm查看cpu使用情况我的电脑是8核的如下图 过高的 CPU 使用率可能是我们的程序代码性能有问题导致的。可以切换到抽样器对cpu进行采样可以擦看到那
个方法占用的cpu最高然后进行优化。 从图中可以看出cpuFix方法使用cpu最多然后就可以进行响应的优化了。
8、查看线程快照发现死锁问题
Java 语言能够很好的实现多线程应用程序。当我们对一个多线程应用程序进行调试或者开发后期做性能调优的时
候往往需要了解当前程序中所有线程的运行状态是否有死锁、热锁等情况的发生从而分析系统可能存在的问
题。
在 VisualVM 的监视标签内我们可以查看当前应用程序中所有活动线程Live threads和守护线程Daemon
threads的数量等实时信息。
可以查看线程快照发现系统的死锁问题。
下面我们将通过visualvm来排查一个死锁问题。
步骤一运行下面的代码
package com.example.controller;public class Demo7 {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生成线程堆栈信息 可以看到Found one Java-level deadlock包含了导致死锁的代码。
Found one Java-level deadlock:thread2:waiting to lock monitor 0x000000001d201fd8 (object 0x000000076b5ff7c8, a com.example.controller.Demo7$Obj1),which is held by thread1
thread1:waiting to lock monitor 0x000000001d203478 (object 0x000000076b601e50, a com.example.controller.Demo7$Obj2),which is held by thread2Java stack information for the threads listed above:thread2:at com.example.controller.Demo7$SynAddRunalbe.run(Demo7.java:47)- waiting to lock 0x000000076b5ff7c8 (a com.example.controller.Demo7$Obj1)- locked 0x000000076b601e50 (a com.example.controller.Demo7$Obj2)at java.lang.Thread.run(Thread.java:745)
thread1:at com.example.controller.Demo7$SynAddRunalbe.run(Demo7.java:40)- waiting to lock 0x000000076b601e50 (a com.example.controller.Demo7$Obj2)- locked 0x000000076b5ff7c8 (a com.example.controller.Demo7$Obj1)at java.lang.Thread.run(Thread.java:745)Found 1 deadlock.上面这段信息可以看出thread1持有Obj1对象的锁等待获取Obj2的锁thread2持有Obj2的锁等待获取
Obj1的锁导致了死锁。