使用visualvm监控Java程序性能三——浏览堆dump文件

堆dump,即堆转储,其实是一个当前JVM堆内存所有对象在某个时间点上的快照。堆dump用来将当前应用程序的堆内存中的数据信息保存为文件,并可以快速浏览文件中的内容,查询对象分配信息。 在VisualVM中,堆dump的入口很多,可以再应用程序右键,选择堆dump;也可以打开主窗口的“监视”tab页,点击右上角有堆dump按钮;还可以打开抽样器tab页,进行内存抽样后,点击工具栏上的堆dump按钮。 1. 打开堆dump 执行完堆dump后,主窗口会打开一个堆dump的页面,同时应用程序节点会增加一个headdump+时间子节点,可以直接打开该节点来浏览堆dump文件信息,如图所示: 堆dump文件存储后缀为.hprof,除了能够看到本地堆dump文件,也可以通过菜单栏的文件-装入打开他人分享的dump文件: 2. 浏览堆dump文件信息 堆dump tab页包含了几个子标签页面:概要、类、实例、OQL控制台,我们重点说下前三个。 2.1. 概要 显示了转储堆dump时的信息,包括基本信息、环境信息、系统属性和线程信息,例如你可以看到堆dump时间、文件存放位置、大小等。 2.2. 类 类视图显示类的列表,以及该类引用的实例的数量和百分占比、类所有实例的大小和百分占比。您可以通过在实例视图中右键单击名称和选择“在实例图中显示”或者直接双击类来查看特定类的实例列表: 通过类视图,可以整体上明确哪些类实例数多,占用资源高。 可以通过最下方的“类目过滤器”来搜索类,点击漏斗形状的图标可以选择筛选类型,例如包含/不包含类名称、正则匹配、搜索子类等。例如,搜索类名包含EsSyncTask的所有类,如下图所示: 2.3. 实例数 当在类视图选择查询具体某一个类的实例时(右键或者双击),此时就打开了该类的实例视图。当您从实例窗格中选择一个实例时,VisualVM将显示该类的字段,并在各自的窗格中引用该类。 除了显示了具体的类和概要信息(实例数量、大小、总大小等)外,实例视图还有几个面板: 实例数:显示当前类的实例列表,点击具体的某一个实例可以在字段和引用面板查看实例的字段信息和引用了的对象 字段:显示当前选择的实例的具体字段,包括字段名称、类型、字段值等 引用:递归显示当前所有引用了该类的类实例,该面板会一层层递归显示引用,包括引用实例的再引用。通过引用面板,可以跟踪对象的引用情况,以便找到具体的类,从而优化代码。 通过右键点击实例或者在引用面板右键,可以查看最近垃圾回收根节点。 接下来,我们来编一个实例程序,看看堆dump的情况,代码如下: public class HeaddumpTest { public static void main(String[] args) { Refrence ref = new Refrence(); int id = 0; while (true) { ref.add(new MyClass(id++, "myclass" + id)); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Refrence { private List<MyClass> myClasses = new ArrayList<>(); public void add(MyClass myClass) { myClasses.add(myClass); } public List<MyClass> getMyClasses() { return myClasses; } public void setMyClasses(List<MyClass> myClasses) { this.myClasses = myClasses; } } class MyClass { private int id; private String name; MyClass(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } ...

2018-04-24 · 1 min · 168 words · Hank

使用visualvm监控Java程序性能二——主窗口功能详解

无论是本地还是远程节点,双击或者右键打开应用程序,会直接在主窗口打开程序监控页。主窗口包括几个子页面:概述、监视、线程、抽样器,如果是本地程序且支持分析器还会显示Profiler页,根据安装插件的不同,还可能会显示一些插件的页面,例如MBeas等。 Figure 1. 主窗口界面 1. 概述页 概述页显示了应用程序和运行时环境的基本信息,如下图所示: Figure 2. 概述页界面 概述信息包括基本参数、保存的数据、详细信息几个部分。 1.1. 基本参数 基本参数描述了应用程序的一些参数信息,包括如下信息: PID:应用程序的进程ID 主机:应用程序运行的系统地址 主类:运行了main方法的类 参数:应用启动时所传递的参数信息,例如传递给main方法的参数列表 JVM:当前的JVM信息 Java:当前使用的JDK信息 Java Home:JDK的位置 JVM标志:启动JDK时JVM使用的的标志 出现OOME时生产堆dump:当前出现OOME时生产堆dump功能的开启/禁用状态 除了基本信息外,还包括两个可以自主选择显示或隐藏的功能(右上角):保存的数据和详细信息。 1.2. 保存的数据 显示VisualVM存储的当前应用程序的信息,例如线程dump的数量、堆dump和快照的数量等。 1.3. 详细信息 包括两个标签:JVM参数和系统属性。 JVM参数:配置的JVM启动的参数信息,例如堆大小; 系统属性:JVM运行的系统属性,例如用户目录、文件编码; 2. 监视页 监视tab页展示了监听了当前应用程序的整体情况,包括几个指标:CPU、内存、类、线程,它们都以直观的图形方式展现。 Figure 3. 监视页界面 2.1. CPU 该图展示了CPU的使用百分比走势,包括执行垃圾回收活动的时间等。可以从该图查看应用程序是否耗费CPU,是否频繁的进行垃圾回收,以便优化代码或者调整JVM内存设置。 2.2. 内存 反映了内存的占用情况,包括内存大小、最大值和已经使用的大小。内存情况又包括两部分:堆和Metaspace。 堆:该页展示了堆内存的大小和堆内存使用走势情况。 Metaspace:即元空间,JDK8移除了永久代(PermGen),而类的元数据信息被存储在了Metaspace,具体请看 这里。该标签反映了元空间内存的使用情况。 2.3. 类 类视图显示了已经加载的类数量和共享类的数量走势情况。 2.4. 线程 线程视图显示了应用程序在JVM中生存和守护线程的数量走势情况。如果您想在特定的时间点捕获和查看应用程序线程的精确数据,可以打开线程标签页,使用VisualVM进行线程转储(稍后详述)。 除了这四个图表,监视页还有两个重要的功能:执行垃圾回收和堆dump。 执行垃圾回收:立即触发垃圾回收 堆dump:执行堆dump,并在新的标签页打开,以查看对dump的详细信息(同右键应用程序–堆dump)。 通常,需要长期监控应用程序的情况,幸好这不会带来太大的开销。 我们看一个OOM的例子,看看VisualVM的监视页的监控情况。代码如下: public static void main(String[] args) { List<Object> objects = new ArrayList<>(); new Thread(() -> { while (true) { objects.add(new Object()); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } ...

2018-04-21 · 2 min · 402 words · Hank

使用VisualVM监控Java程序性能一——简介

Java应用程序难免遇到性能问题,例如常见的OutOfMemmoryError,又或者是出现内存泄漏的错误,又或是程序运行一段时间就卡死了,CPU或者内存占用率高,甚至造成系统崩溃,等等。出现性能问题时,往往难以分析和跟踪。不过,可以借助于一些性能分析工具,来监测程序性能,从而找出影响性能的问题所在,以便进行优化。本文的VisualVM就是一款比较强大的性能分析工具。 先来看看性能分析的几种方式: 性能分析的主要方式 性能分析常用的有以下几种方式 * 监视:监视是一种用来查看应用程序运行时行为的一般方法。通常会有多个视图(View)分别实时地显示 CPU 使用情况、内存使用情况、线程状态以及其他一些有用的信息,以便用户能很快地发现问题的关键所在。 * 转储(dump):性能分析工具从内存中获得当前状态数据并存储到文件用于静态的性能分析。Java 程序是通过在启动 Java 程序时添加适当的条件参数来触发转储操作的。它包括以下三种: 核心dump:JVM 生成的本地系统的转储。一般的,系统转储数据量大,需要平台相关的工具去分析,如 Windows 上的 windbg 和 Linux 上的 gdb。 Jvm dump:JVM 内部生成的格式化后的数据,包括线程信息,类的加载信息以及堆的统计数据。通常也用于检测死锁。 堆dump:JVM 将所有对象的堆内容存储到文件。 * 快照:应用程序启动后,性能分析工具开始收集各种运行时数据,其中一些数据直接显示在监视视图中,而另外大部分数据被保存在内部,直到用户要求获取快照,基于这些保存的数据的统计信息才被显示出来。快照包含了应用程序在一段时间内的执行信息,通常有 CPU 快照和内存快照两种类型。 CPU 快照:主要包含了应用程序中函数的调用关系及运行时间,这些信息通常可以在 CPU 快照视图中进行查看。 内存快照:主要包含了内存的分配和使用情况、载入的所有类、存在的对象信息及对象间的引用关系等。这些信息通常可以在内存快照视图中进行查看。 * 性能分析:性能分析是通过收集程序运行时的执行数据来帮助开发人员定位程序需要被优化的部分,从而提高程序的运行速度或是内存使用效率,主要有以下三个方面: CPU 性能分析:CPU 性能分析的主要目的是统计函数的调用情况及执行时间,或者更简单的情况就是统计应用程序的 CPU 使用情况。通常有 CPU 监视和 CPU 快照两种方式来显示 CPU 性能分析结果。 内存性能分析:内存性能分析的主要目的是通过统计内存使用情况检测可能存在的内存泄露问题及确定优化内存使用的方向。通常有内存监视和内存快照两种方式来显示内存性能分析结果。 线程性能分析:线程性能分析主要用于在多线程应用程序中确定内存的问题所在。一般包括线程的状态变化情况,死锁情况和某个线程在线程生命期内状态的分布情况等 — 使用 VisualVM 进行性能分析及调优 https://www.ibm.com/developerworks/cn/java/j-lo-visualvm 1. VisualVM简介 VisualVM是集成JDK命令行工具和轻量级分析功能的可视化分析工具,设计用于开发和生产时间的使用。它提供了一个可视化界面,用于查看基于Java技术、运行于JVM上的应用程序(Java应用程序)的详细信息。 VisualVM组织Java开发工具包(JDK)工具检索的JVM软件的数据,并以一种使您能够快速查看多个Java应用程序的数据的方式提供信息。您可以查看在远程主机上运行的本地应用程序和应用程序的数据。您还可以捕获有关JVM软件实例的数据,并将数据保存到您的本地系统中,以供后期查看或与其他用户共享。 VisualVM完全免费,它通过 jvmstat、JMX、SA(Serviceability Agent)以及 Attach API 等多种方式从程序运行时获得实时数据,从而进行动态的性能分析。同时,它能自动选择更快更轻量级的技术尽量减少性能分析对应用程序造成的影响,提高性能分析的精度。 2. VisualVM安装 从JDK6开始,VisualVM已经成为JDK自带工具,名称叫做jvisualvm,位于%JAVA_HOME%/bin/jvisualvm.exe,执行即可启动。 需要注意的是,从Oracle JDK 9开始,Java VisualVM迁移到GraalVM,这是在Oracle实验室开发的一种创新的、高性能的多语言虚拟机。详情请参阅 Graal VisualVM页面。 ...

2018-04-20 · 1 min · 114 words · Hank