深入理解Java虚拟机-如何利用VisualVM对高并发项目进行性能分析
前面在学习JVM的知识的时候,一般都需要利用相关参数进行分析,而分析一般都需要用到一些分析的工具,因为一般使用IDEA,而VisualVM对于IDEA也不错,所以就选择VisualVM来分析JVM性能,这篇文章就介绍一下如何利用VisualVM进行性能分析,以及在分析之前需要知道一些GC优化的原则,GC优化的目的,以及遇到问题时怎么去解决问题的方法。
1 为什么需要
开发大型 Java 应用程序的过程中难免遇到内存泄露、性能瓶颈等问题,比如文件、网络、数据库的连接未释放,未优化的算法等。随着应用程序的持续运行,可能会造成整个系统运行效率下降,严重的则会造成系统崩溃。为了找出程序中隐藏的这些问题,在项目开发后期往往会使用性能分析工具来对应用程序的性能进行分析和优化。
VisualVM 是一款免费的性能分析工具。它通过 jvmstat、JMX、SA(Serviceability Agent)以及 Attach API 等多种方式从程序运行时获得实时数据,从而进行动态的性能分析。同时,它能自动选择更快更轻量级的技术尽量减少性能分析对应用程序造成的影响,提高性能分析的精度。
2 如何安装
这里有两种方式:
- 没有按照IDEA插件
如果没有按照IDEA插件的话,我们需要找到JDK的按照目录bin下找到如下执行程序。
然后双击执行,就会出现界面,如下;
但是,我们一般使用IDEA,所以会使用插件,就是下面这种方式。
- 按照IDEA插件
先在插件中找到VisualVM安装;
安装了之后,在运行的地方就会多出现两个VisualVM的运行按钮;
这样运行程序之后,就可以自动打开VisualVM程序了。
3 基本介绍
这一部分先对这个工具做一个简要的介绍,看看基本有哪些我们会用到的功能。
在没有添加其他插件的时候,是只有下面几个功能的。
3.1 概述
如上图所示,概述基本上都是我们的系统属性、运行程序时设置的JVM参数等信息的展示,所以,这一部分可以让我们查看这些信息。
3.2 监视
监视这个界面的功能还是很有作用的,可以看到cup运行情况、堆的使用情况、类的情况以及线程的动态情况。
因此,我们可以利用这个界面查看cpu情况好不好,更重要的是,我们可以查看堆的使用情况,这对于我们分析JVM还是非常重要的。
3.3 线程
如上图所以,可以看到所有的线程的情况,是运行、休眠、等待、驻留、监视等情况。
注意, 以上这些都不是关键,关键是VisualVM中还有一个很重要的功能,可以添加插件获取更多的功能。
3.4 插件添加
正是因为有了插件的扩展功能,所以这个工具才如此强大,VisualVM可以做到以下:
- 显示虚拟机进程以及进程的配置、环境信息、jps、jinfo。
- 监视应用程序的cpu、GC、堆、方法区以及线程的信息(jstat、jstack)。
- dump以及分析堆转存储快照(jmap、jhat)。
- 还有很多其他的功能。
在工具->找到可用插件,安装即可。
下一部分我们就利用已经安装的插件Visual GC
进行分析。
4 利用Visual GC
分析虚拟机内存区域
这部分会用到一些Java虚拟机的一些基础知识,所以,查看这部分之前,请先查看这篇文章:。
在这个界面分为以下几个部分。
- space(Metaspace(元数据)、Old老年代、新生代(Eden、S0、S1))
- Graphs(Compile Time(编译时间)、Class Loader Time(类加载时间)、GC Time(垃圾收集时间)、Eden Space、Survivor 0、Survivor 1、Old Gen、Metaspace)
- Histogram(Parameters参数设置)
那么知道这些参数之后,怎么去分析虚拟机到底运行是好是坏呢,这个时候,我们需要了解一些Java虚拟机基础的优化知识。
首先,需要了解一些GC优化的原则。
- 多数的Java应用不需要在服务器上进行GC优化;
- 多数导致GC问题的Java应用,都不是因为我们参数设置错误,而是代码问题;
- 在应用上线之前,先考虑将机器的JVM参数设置到最优(最适合);
- 减少创建对象的数量;
- 减少使用全局变量和大对象;
- GC优化是到最后不得已才采用的手段;
- 在实际使用中,分析GC情况优化代码比优化GC参数要多得多;
另外,我们需要知道我们GC优化的目的。
- 将转移到老年代的对象数量降低到最小;
- 减少full GC的执行时间;
一般,我们需要执行的有以下几点;
- 减少使用全局变量和大对象;
- 调整新生代的大小到最合适;
- 设置老年代的大小为最合适;
- 选择合适的GC收集器;
至于怎么算合适,后面我会通过一个实例讲解。
其实,如果想要知道更多JVM内存分配和回收策略的原理,可以查看这篇文章:JVM内存分配和回收策略的原理。
一般我们执行了我们的程序之后,接下来就是需要查看GC的状态了,接着分析结果,判断是否需要进行优化。
一般如果达到以下的指标,就不需要进行GC了。
Minor GC
执行时间不到50ms
,Minor GC
执行不频繁,约10
秒一次;Full GC
执行时间不到1s
,Full GC
执行频率不算频繁,不低于10
分钟1次;
实例 1
我们先看一个GC状态需要优化的例子,在这个实例中,我们给堆分配的最大最小的值都是64M
(很小的堆大小)。
GC状态差情况分析
/**
* VM Args:-Xms64m -Xmx64m -XX:+HeapDumpOnOutOfMemoryError
* @author 欧阳思海
*/
public class HeapTest {
static class StaticObject {
}
public static void main(String[] args) {
List<StaticObject> list = new ArrayList<StaticObject>();
int i = 1;
//不断的向堆中添加对象
while (true) {
list.add(new StaticObject());
i++;
System.out.println(i);
System.out.println(list.size());
}
}
}
由于分配的堆内存太小,所以导致,堆溢出。
接着我们查看一下Visual GC
的监视情况。
- 监视界面情况
我们可以从堆的使用情况看出,基本已经使用完。
- Visual GC监视情况
从上图可知,在短短的运行时间中,Eden进行了49次GC,虽然时间短,但是能说明一个问题,新生代堆内存分配的空间太小,导致频繁GC。
同时,Old老年代也进行了33次GC,虽然运行时间也在不需要优化的范围内,而且从Survivor可以看出,基本没有GC,说明这些都是大对象,直接进入到了Old老年代,导致GC频繁。
所以,我们需要进行的优化就是加大新生代和老年代堆内存的大小,同时减少大对象的产生。
参数优化分析
我们将VM参数改为:-Xms512m -Xmx512m -Xmn128m -XX:+HeapDumpOnOutOfMemoryError
,运行大概5分钟再次查看结果。
首先没有出现堆内存溢出。
- 监视情况
加大了堆内存,所以堆内存没有出现问题。
- Visual GC监视情况
加大了堆内存之后,Eden新生代进行了66次GC,使用时间3.381s基本满足要求(执行时间不到50ms,Minor GC执行不频繁,约10秒一次),同时老年代old进行了2次GC,使用时间4.127s,这里还是有待优化的,不太满足优化要求。
- dump文件分析
点击堆 dump这个按钮就会生成 dump文件,我们可以分析类及对象的一些情况。
分析之后发现,StaticObject对象大多,没有进行GC,问题主要在这里,所以,下一步需要解决这个问题。
通过以上分析可以说明一个问题,加大了堆内存之后,新生代和老年代的GC情况大大的改善了,但是还有大对象的问题,所以还有待优化。
修改大对象,进行GC
修改程序,如下:
/**
* VM Args:-Xms512m -Xmx512m -Xmn128m -XX:+HeapDumpOnOutOfMemoryError
*
* @author 欧阳思海
*/
public class HeapTest {
/* static class StaticObject {
}*/
public static void main(String[] args) {
int i = 1;
while (true) {
i++;
System.out.println(i);
}
}
}
- 监视情况
堆一直运行良好。
- Visual GC监视情况
这次相对于上次相比,老年代的情况已经改善了,没有GC,说明大对象不存在了。
通过上面的分析跟优化,就满足GC的需求了,不需要再优化了。
Java虚拟机深入理解系列全部文章更新中...
- 深入理解Java虚拟机-Java内存区域透彻分析
- 深入理解Java虚拟机-常用vm参数分析
- 深入理解Java虚拟机-JVM内存分配与回收策略原理,从此告别JVM内存分配文盲
- 深入理解Java虚拟机-如何利用JDK自带的命令行工具监控上百万的高并发的虚拟机性能
- 深入理解Java虚拟机-如何利用VisualVM对高并发项目进行性能分析
- 深入理解Java虚拟机-你了解GC算法原理吗
5 总结
通过上面的分析及使用,VisualVM基本的使用以及如何利用VisualVM进行Java虚拟机优化相信你已经掌握了,如果还想了解更过关于Java虚拟机的知识及优化文章,请看本系列的其他文章。
1、原创不易,老铁,文章需要你的 点赞 让更多的人看到,希望能够帮助到大家!
2、文章有不当之处,欢迎指正,如果喜欢微信阅读,你也可以关注我的微信公众号:
好好学java
,公众号已有 6W 粉丝。
深入理解Java虚拟机-如何利用VisualVM对高并发项目进行性能分析的更多相关文章
- JVM 利用 VisualVM 对高并发项目进行性能分析(转)
出处: 深入理解 Java 虚拟机-如何利用 VisualVM 对高并发项目进行性能分析 前面在学习JVM的知识的时候,一般都需要利用相关参数进行分析,而分析一般都需要用到一些分析的工具,因为一般使 ...
- 【深入理解JAVA虚拟机】第5部分.高效并发.1.Java内存模型与线程。
1.概述 摩尔定律:描述处理器晶体管数量与运行效率之间的发展关系.Amdahl定律:通过系统中并行化与串行化的比重来描述多处理器系统能获得的运算加速能力. 从摩尔定律到Amdahl定律的转变,代表了近 ...
- 【深入理解JAVA虚拟机】第5部分.高效并发.2.线程安全和锁优化
1 概述 对于这部分的主题“高效并发”来讲,首先需要保证并发的正确性,然后在此基础上实现高效. 2 线程安全 <Java Concurrency In Practice> 的作者Brian ...
- 深入理解Java虚拟机--上
深入理解Java虚拟机--上 第2章 Java内存区域和内存溢出异常 2.2 运行时数据区域 图 2-1 Java虚拟机运行时数据区 2.2.1 程序计数器 程序计数器可以看作是当前线程所执行的字节码 ...
- 《深入理解Java虚拟机》虚拟机性能监控与故障处理工具
上节学习回顾 从课本章节划分,<垃圾收集器>和<内存分配策略>这两篇随笔同属一章节,主要是从理论+实验的手段来讲解JVM的内存处理机制.好让我们对JVM运行机制有一个良好的概念 ...
- 深入理解java虚拟机系列(一):java内存区域与内存溢出异常
文章主要是阅读<深入理解java虚拟机:JVM高级特性与最佳实践>第二章:Java内存区域与内存溢出异常 的一些笔记以及概括. 好了開始.假设有什么错误或者遗漏,欢迎指出. 一.概述 先上 ...
- 深入理解Java虚拟机--下
深入理解Java虚拟机--下 参考:https://www.zybuluo.com/jewes/note/57352 第10章 早期(编译期)优化 10.1 概述 Java语言的"编译期&q ...
- 《深入理解Java虚拟机:JVM高级特性与最佳实践》【PDF】下载
<深入理解Java虚拟机:JVM高级特性与最佳实践>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062566 内容简介 作为一位 ...
- Java虚拟机内存溢出异常--《深入理解Java虚拟机》学习笔记及个人理解(三)
Java虚拟机内存溢出异常--<深入理解Java虚拟机>学习笔记及个人理解(三) 书上P39 1. 堆内存溢出 不断地创建对象, 而且保证创建的这些对象不会被回收即可(让GC Root可达 ...
随机推荐
- http的长连接和短连接(史上最通俗!)
1.以前的误解 很久之前就听说过长连接的说法,而且还知道HTTP1.0协议不支持长连接,从HTTP1.1协议以后,连接默认都是长连接.但终究觉得对于长连接一直懵懵懂懂的,有种抓不到关键点的感觉. 今天 ...
- jquery--获取input radio单选框的值
html <input type="radio" name="sex" value="man" checked> man < ...
- JS-this的使用
做前端开发已经半年之多了,前几天看见apply时心生疑惑,于是查阅了好多资料但还是不太理解,只知道是源于this的问题,今天偶然看到了阮一峰大佬的讲解js中的this问题(http://www.rua ...
- powerbuilder连接oracle数据库
一.打开已经安装好的pb9.0,主界面菜单栏有个两个圆柱形就行数据库连接,点击database. 二.选择oracle版本,由于数据库版本是9i,可以使用084 oracle8/8i.右键--选择ne ...
- 解决 C# .NET WebClient WebRequest请求缓慢的问题
[编程环境]Visual Studio 2010, NET4.0 [开发语言]C#, 理论上VB.NET等依赖.NET Framework框架的语言均受此影响 [问题描述] 使用HttpWebRequ ...
- 小程序云函数调用http或https请求外部数据
参考网址 https://blog.csdn.net/qiushi_1990/article/details/101220920 小程序云函数调用http或https请求外部数据 原创编程小石头 发布 ...
- stm32 串口发送字符串丢失第一个字节
使用stm32f103调试串口通讯时,上电后发送的字符串的第一个字节丢失. 发送数据GpuSend("SPG(2);"); 接收端收到的数据为:PG(2);,第一个字符丢失. 出现 ...
- 201771010131-王之泰 实验一 软件工程准备—<通读《现代软件工程—构建之法》后所思所想>周学习总结
项目 内容 作业所属课程 https://www.cnblogs.com/nwnu-daizh/ 作业要求 https://www.cnblogs.com/nwnu-daizh/p/12369881. ...
- ADO.Net实体数据模型添加DB-First/Code First报错
Authentication method 'caching_sha2_password' not supported by any of the available plugins. 解决办法: 1 ...
- spring boot中的底层配置文件application.yam(application.property)的装配原理初探
*在spring boot中有一个基础的配置文件application.yam(application.property)用于对spring boot的默认设置做一些改动. *在spring boot ...