当前位置: 首页 > 科技观察

深入理解Java虚拟机-如何利用VisualVM对高并发项目进行性能分析

时间:2023-03-17 10:13:10 科技观察

深入理解Java虚拟机——如何使用VisualVM对高并发项目进行性能分析一般用IDEA,IDEA用VisualVM也不错,所以选择VisualVM分析JVM性能。本文介绍如何使用VisualVM进行性能分析,分析前需要了解GC优化的一些原则,以及GC优化的目的。以及遇到问题时如何解决。1为什么需要开发大型Java应用程序?在开发大型Java应用的过程中,难免会遇到文件、网络、数据库连接未释放,算法未优化等内存泄漏和性能瓶颈等问题。随着应用程序的持续运行,可能会导致整个系统的运行效率下降,严重时可能导致系统崩溃。为了发现程序中隐藏的这些问题,在项目开发的后期往往会使用性能分析工具对应用程序的性能进行分析和优化。VisualVM是一款免费的性能分析工具。它通过jvmstat、JMX、SA(ServiceabilityAgent)、AttachAPI等多种方式从程序运行时获取实时数据,进行动态性能分析。同时,它可以自动选择更快、更轻的技术,最大限度地减少性能分析对应用程序的影响,提高性能分析的准确性。2如何安装有两种方式:不带IDEA插件如果不带IDEA插件,我们需要找到JDK,在bin目录下找到如下执行程序。然后双击执行,出现界面,如下;但是我们一般都是用IDEA,所以会用到插件,也就是下面的方法。根据IDEA插件,首先在插件中找到VisualVM安装;安装完成后,运行处会多出现两个VisualVM运行按钮;这样运行程序后,VisualVM程序就可以自动打开了。3基本介绍这部分首先对这个工具做一个简单的介绍,并看到我们将要使用的基本功能。在不添加其他插件的情况下,只有以下功能。3.1Overview如上图所示,Overview基本上是对我们的系统属性,运行程序时设置的JVM参数等信息的展示,所以这部分可以让我们查看这些信息。3.2监控这个接口的监控功能还是很有用的。可以看到cup的运行状态,heap的使用情况,class的状态,线程的动态。因此,我们可以通过这个接口来查看cpu是否良好,更重要的是可以查看heap的使用情况,这对于我们分析JVM来说非常重要。3.3线程如上图所示,可以看到所有线程的状态,如running、sleeping、waiting、resident、monitoring等,注意以上都不是critical。关键是VisualVM还有一个很重要的功能,就是可以通过添加插件来获得更多的功能。3.4添加插件正是因为插件的扩展功能,这个工具才如此强大。VisualVM可以做以下事情:显示虚拟机进程和进程配置、环境信息、jps、jinfo。监控应用程序的cpu、GC、heap、方法区和线程信息(jstat、jstack)。转储和分析堆存储快照(jmap、jhat)。还有很多其他功能。在Tools->Installthem中找到可用的插件。在接下来的部分中,我们将使用安装的插件VisualGC进行分析。4使用VisualGC分析虚拟机内存区域这部分会用到Java虚拟机的一些基础知识,所以在看这部分之前,请先看看这篇文章:。该界面分为以下几个部分。space(Metaspace(元数据),Oldage,newgeneration(Eden,S0,S1))Graphs(CompileTime(编译时间),ClassLoaderTime(类加载时间),GCTime(垃圾收集时间),EdenSpace,Survivor0,Survivor1,OldGen,Metaspace)Histogram(Parameters参数设置)知道这些参数后,如何分析虚拟机是否运行良好?这时候,我们就需要了解一些Java虚拟机优化的基本知识。首先,你需要了解GC优化的一些原则。大多数Java应用程序不需要在服务器上进行GC优化;大多数导致GC问题的Java应用不是参数设置错误导致的,而是代码问题;应用上线前,考虑将机器的JVM参数设置为最优(Mostsuitable);减少创建对象的数量;减少全局变量和大对象的使用;GC优化是最后的手段;在实际使用中,分析GC条件来优化代码远不止优化GC参数那么简单;另外,我们需要知道我们GC优化的目的。尽量减少转移到老年代的对象数量;减少fullGC的执行时间;一般来说,我们需要实现以下几点;减少全局变量和大对象的使用;将新生代??的大小调整到最合适;设置老年代的大小是最合适的;选择合适的GC收集器;至于如何计算出合适的尺寸,后面会通过例子来说明。其实如果你想了解更多关于JVM内存分配和回收策略的原理,可以看看这篇文章:JVM内存分配和回收策略原理。一般我们执行完自己的程序之后,接下来就是查看GC的状态,然后分析结果来判断是否需要优化。一般满足以下指标,就不需要GC了。MinorGC执行时间小于50ms,MinorGC执行不频繁,大约10秒一次;FullGC执行时间小于1s,FullGC执行频率不频繁,不少于10分钟一次;Example1先来看一个GC需要优化state的例子。在这个例子中,我们分配给堆的最大值和最小值都是64M(一个小的堆大小)。GC状态分析/***VMArgs:-Xms64m-Xmx64m-XX:+HeapDumpOnOutOfMemoryError*@author欧阳思海*/publicclassHeapTest{staticclassStaticObject{}publicstaticvoidmain(String[]args){Listlist=newArrayList();inti=1;//不断向堆中添加对象while(true){list.add(newStaticObject());i++;System.out.println(i);System.out.println(list.size());}}}因为分配的堆内存太小,导致堆溢出。然后我们看VisualGC的监控。从监控界面我们可以看到heap的使用情况,基本已经用完了。可视化GC监控情况从上图可以看出,在很短的运行时间内,Eden执行了49次GC。时间虽短,却能说明一个问题。新生代堆内存分配的空间太小,导致频繁GC。与此同时,Oldgeneration也进行了33次GC。虽然运行时间在不需要优化的范围内,而从Survivor可以看出基本没有GC,说明这些都是大对象,直接进入了Oldgeneration,导致GC频繁。因此,我们需要优化的是增加新生代和老年代的堆内存大小,同时减少大对象的生成。参数优化分析我们将VM参数改为:-Xms512m-Xmx512m-Xmn128m-XX:+HeapDumpOnOutOfMemoryError,运行5分钟左右,再次查看结果。首先,没有堆内存溢出。监控情况增加了堆内存,所以堆内存没有问题。VisualGC监控情况增加堆内存后,新生代Eden执行了66次GC,3.381s的使用时间基本满足要求(执行时间小于50ms,MinorGC执行不频繁,大概有一次每10秒)。进行了两次GC,使用时间为4.127s。这里还有优化的空间,不太符合优化要求。转储文件分析点击堆转储按钮,生成一个转储文件,我们可以分析类和对象的一些情况。经过分析,发现大部分的StaticObject对象都没有被GC过。主要问题就在这里,接下来就是解决这个问题了。以上分析可以说明一个问题。增加堆内存后,新生代和老年代的GC情况有了很大的改善,但是仍然存在大对象的问题,需要优化。修改大对象,执行GC修改流程如下:[]args){inti=1;while(true){i++;System.out.println(i);}}}监控情况heap一直运行良好。与上次相比,本次VisualGC的监控情况在老年代有所改善。没有GC,说明大对象不存在。通过上面的分析和优化,满足了GC的需求,不需要进一步优化。5小结通过以上的分析和使用,相信您已经掌握了VisualVM的基本使用以及如何使用VisualVM优化Java虚拟机。如果您想了解更多关于Java虚拟机和优化的文章,请阅读本系列的其他文章。文章。1.原创不易,老铁,文章需要你的点赞才能让更多人看到,希望对大家有所帮助!2.文章有不当之处,请指正。喜欢看微信的也可以关注我的微信公众号:努力学java,公众号已经有6W粉丝了。