jvisualvm分析dump文件(jvisualvm分析hprof)

jvisualvm分析dump文件(jvisualvm分析hprof)p 前面在学习 JVM 的知识的时候 一般都需要利用相关参数进行分析 而分析一般都需要用到一些分析的工具 因为一般使用 IDEA 而 VisualVM 对于 IDEA 也不错 所以就选择 VisualVM 来分析 JVM 性能 这篇文章就介绍一下 strong 如何利用 VisualVM 进行性能分析 strong 以及在分析之前需要知道一些 p

大家好,我是讯享网,很高兴认识大家。




讯享网

 <p>前面在学习JVM的知识的时候,一般都需要利用相关参数进行分析,而分析一般都需要用到一些分析的工具,因为一般使用IDEA,而VisualVM对于IDEA也不错,所以就选择VisualVM来分析JVM性能,这篇文章就介绍一下<strong>如何利用VisualVM进行性能分析</strong>,以及在分析之前需要知道一些<strong>GC优化的原则</strong>,<strong>GC优化的目的</strong>,以及<strong>遇到问题时怎么去解决问题的方法</strong>。</p><p><h5>1 为什么需要</h5></p><p>开发大型 Java 应用程序的过程中难免遇到内存泄露、性能瓶颈等问题,比如文件、网络、数据库的连接未释放,未优化的算法等。随着应用程序的持续运行,可能会造成整个系统运行效率下降,严重的则会造成系统崩溃。为了找出程序中隐藏的这些问题,在项目开发后期往往会使用性能分析工具来对应用程序的性能进行分析和优化。</p><p>VisualVM 是一款免费的性能分析工具。它通过 jvmstat、JMX、SA(Serviceability Agent)以及 Attach API 等多种方式从程序运行时获得实时数据,从而进行动态的性能分析。同时,它能自动选择更快更轻量级的技术尽量减少性能分析对应用程序造成的影响,提高性能分析的精度。</p><p><h5>2 如何安装</h5></p><p>这里有两种方式:</p><p><ul><li>没有按照IDEA插件</li></ul></p><p>如果没有按照IDEA插件的话,我们需要找到JDK的按照目录bin下找到如下执行程序。</p><p>然后双击执行,就会出现界面,如下;</p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2020%2F0120%2Fb4d004e3j00q4eseb0025c000xc00ipm.jpg&thumbnail=660x&quality=80&type=jpg"/><br/></p><p>但是,我们一般使用IDEA,所以会使用插件,就是下面这种方式。</p><p>按照IDEA插件</p><p>先在插件中找到VisualVM安装;</p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2020%2F0120%2F4020bcb5j00q4eseb0032c000r800hpm.jpg&thumbnail=660x&quality=80&type=jpg"/><br/></p><p>安装了之后,在运行的地方就会多出现两个VisualVM的运行按钮;</p><p>这样运行程序之后,就可以自动打开VisualVM程序了。</p><p><h5>3 基本介绍</h5></p><p>这一部分先对这个工具做一个简要的介绍,看看基本有哪些我们会用到的功能。</p><p>在没有添加其他插件的时候,是只有下面几个功能的。</p><p><strong>3.1 概述</strong></p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2020%2F0120%2F325f5e47j00q4eseb002jc000q400fgm.jpg&thumbnail=660x&quality=80&type=jpg"/><br/></p><p>如上图所示,概述基本上都是我们的<strong>系统属性、运行程序时设置的JVM参数</strong>等信息的展示,所以,这一部分可以让我们查看这些信息。</p><p><strong>3.2 监视</strong></p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2020%2F0120%2F5610c817j00q4eseb002cc000qa00f5m.jpg&thumbnail=660x&quality=80&type=jpg"/><br/></p><p>监视这个界面的功能还是很有作用的,可以看到<strong>cup运行情况、堆的使用情况、类的情况以及线程的动态情况</strong>。</p><p>因此,我们可以利用这个界面查看cpu情况好不好,更重要的是,我们可以查看堆的使用情况,这对于我们分析JVM还是非常重要的。</p><p><strong>3.3 线程</strong></p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2020%2F0120%2Ff61ca3dfj00q4eseb002qc000q700fam.jpg&thumbnail=660x&quality=80&type=jpg"/><br/></p><p>如上图所以,可以看到所有的线程的情况,是<strong>运行、休眠、等待、驻留、监视</strong>等情况。</p><p><strong>注意,</strong>以上这些都不是关键,关键是VisualVM中还有一个很重要的功能,可以添加插件获取更多的功能。</p><p><strong>3.4 插件添加</strong></p><p>正是因为有了插件的扩展功能,所以这个工具才如此强大,VisualVM可以做到以下:</p><p><ul><li>显示虚拟机进程以及进程的配置、环境信息、jps、jinfo。</li><li>监视应用程序的cpu、GC、堆、方法区以及线程的信息(jstat、jstack)。</li><li>dump以及分析堆转存储快照(jmap、jhat)。</li><li>还有很多其他的功能。</li></ul></p><p>在工具-&gt;找到可用插件,安装即可。</p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2020%2F0120%2F938c0332j00q4eseb004gc000xc00ipm.jpg&thumbnail=660x&quality=80&type=jpg"/><br/></p><p>下一部分我们就利用已经安装的插件Visual GC进行分析。</p><p><h5>4 利用Visual GC分析虚拟机内存区域</h5></p><p>这部分会用到一些Java虚拟机的一些基础知识,所以,查看这部分之前,请先查看这篇文章:。</p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2020%2F0120%2F25b05861j00q4eseb004ic000xc00k4m.jpg&thumbnail=660x&quality=80&type=jpg"/><br/></p><p>在这个界面分为以下几个部分。</p><p><ul><li>space(Metaspace(元数据)、Old老年代、新生代(Eden、S0、S1))</li><li>Graphs(Compile Time(编译时间)、Class Loader Time(类加载时间)、GC Time(垃圾收集时间)、Eden Space、Survivor 0、Survivor 1、Old Gen、Metaspace)</li><li>Histogram(Parameters参数设置)</li></ul></p><p><strong>那么知道这些参数之后,怎么去分析虚拟机到底运行是好是坏呢</strong>,这个时候,我们需要了解一些Java虚拟机基础的优化知识。</p><p>首先,需要了解一些<strong>GC优化的原则</strong>。</p><p><ul><li>多数的Java应用不需要在服务器上进行GC优化;</li><li>多数导致GC问题的Java应用,都不是因为我们参数设置错误,而是代码问题;</li><li>在应用上线之前,先考虑将机器的JVM参数设置到最优(最适合);</li><li>减少创建对象的数量;</li><li>减少使用全局变量和大对象;</li><li>GC优化是到最后不得已才采用的手段;</li><li>在实际使用中,分析GC情况优化代码比优化GC参数要多得多;</li></ul></p><p>另外,我们需要知道我们<strong>GC优化的目的</strong>。</p><p><ul><li>将转移到老年代的对象数量降低到最小;</li><li>减少full GC的执行时间;</li></ul></p><p>一般,我们需要执行的有以下几点;</p><p><ul><li>减少使用全局变量和大对象;</li><li>调整新生代的大小到最合适;</li><li>设置老年代的大小为最合适;</li><li>选择合适的GC收集器;</li></ul></p><p>至于怎么算合适,后面我会通过一个实例讲解。</p><p>一般我们执行了我们的程序之后,接下来就是需要<strong>查看GC的状态</strong>了,接着<strong>分析结果</strong>,判断<strong>是否需要进行优化</strong>。</p><p>一般如果达到以下的<strong>指标</strong>,就不需要进行GC了。</p><p><ul><li>执行时间不到,执行不频繁,约秒一次;</li><li>Minor GC</li><li>50ms</li><li>Minor GC</li><li>10</li><li>执行时间不到,执行频率不算频繁,不低于分钟1次;</li><li>Full GC</li><li>1s</li><li>Full GC</li><li>10</li></ul></p><p>实例 1</p><p>我们先看一个GC状态需要优化的例子,在这个实例中,我们给堆分配的最大最小的值都是(很小的堆大小)。</p><p>64M</p><p><h5>GC状态差情况分析</h5></p><p>/ * VM Args:-Xms64m -Xmx64m -XX:+HeapDumpOnOutOfMemoryError * @author 欧阳思海 */public class HeapTest { static class StaticObject { } public static void main(String[] args) { List list = new ArrayList(); int i = 1; //不断的向堆中添加对象 while (true) { list.add(new StaticObject()); i++; System.out.println(i); System.out.println(list.size()); } }}</p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2020%2F0120%2F905aa9dcj00q4eseb0012c000oi0039m.jpg&thumbnail=660x&quality=80&type=jpg"/><br/></p><p>由于分配的堆内存太小,所以导致,堆溢出。</p><p>接着我们查看一下的监视情况。</p><p>Visual GC</p><p><ul><li>监视界面情况</li></ul></p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2020%2F0120%2Fa1j00q4eseb003hc000rf00hsm.jpg&thumbnail=660x&quality=80&type=jpg"/><br/></p><p>我们可以从堆的使用情况看出,基本已经使用完。</p><p><ul><li>Visual GC监视情况</li></ul></p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2020%2F0120%2Fc707c9a0j00q4esec0042c000wa00lvm.jpg&thumbnail=660x&quality=80&type=jpg"/><br/></p><p>从上图可知,在短短的运行时间中,<strong>Eden进行了49次GC,虽然时间短,但是能说明一个问题,新生代堆内存分配的空间太小,导致频繁GC</strong>。</p><p>同时,<strong>Old老年代也进行了33次GC,虽然运行时间也在不需要优化的范围内,而且从Survivor可以看出,基本没有GC,说明这些都是大对象,直接进入到了Old老年代,导致GC频繁</strong>。</p><p>所以,我们需要进行的优化就是<strong>加大新生代和老年代堆内存的大小,同时减少大对象的产生</strong>。</p><p><h5>参数优化分析</h5></p><p>我们将VM参数改为:,运行大概<strong>5分钟</strong>再次查看结果。</p><p>-Xms512m -Xmx512m -Xmn128m -XX:+HeapDumpOnOutOfMemoryError</p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2020%2F0120%2F91c6bb4fj00q4eseb000fc000go005vm.jpg&thumbnail=660x&quality=80&type=jpg"/><br/></p><p>首先没有出现堆内存溢出。</p><p><ul><li>监视情况</li></ul></p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2020%2F0120%2F55f9d1bcj00q4eseb0031c000nd00hfm.jpg&thumbnail=660x&quality=80&type=jpg"/><br/></p><p>加大了堆内存,所以堆内存没有出现问题。</p><p><ul><li>Visual GC监视情况</li></ul></p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2020%2F0120%2Ff6caf846j00q4eseb003oc000na00hkm.jpg&thumbnail=660x&quality=80&type=jpg"/><br/></p><p>加大了堆内存之后,<strong>Eden新生代进行了66次GC,使用时间3.381s基本满足要求(执行时间不到50ms,Minor GC执行不频繁,约10秒一次),同时老年代old进行了2次GC,使用时间4.127s,这里还是有待优化的,不太满足优化要求。</strong></p><p><ul><li>dump文件分析</li></ul></p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2020%2F0120%2Fcc8ba8a2j00q4eseb0044c000xc00k4m.jpg&thumbnail=660x&quality=80&type=jpg"/><br/></p><p>点击<strong>堆 dump</strong>这个按钮就会生成 dump文件,我们可以分析类及对象的一些情况。</p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2020%2F0120%2F8a0ea555j00q4eseb002yc000mx00dxm.jpg&thumbnail=660x&quality=80&type=jpg"/><br/></p><p>分析之后发现,<strong>StaticObject对象大多,没有进行GC</strong>,问题主要在这里,所以,下一步需要解决这个问题。</p><p>通过以上分析可以说明一个问题,加大了堆内存之后,新生代和老年代的GC情况大大的改善了,但是还有<strong>大对象的问题</strong>,所以还有待优化。</p><p><h5>修改大对象,进行GC</h5></p><p>修改程序,如下:</p><p>/ * 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); } }}</p><p><ul><li>监视情况</li></ul></p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2020%2F0120%2F82d3b2afj00q4eseb003dc000rj00hvm.jpg&thumbnail=660x&quality=80&type=jpg"/><br/></p><p>堆一直运行良好。</p><p><ul><li>Visual GC监视情况</li></ul></p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2020%2F0120%2F4c287a24j00q4eseb003dc000rc00hkm.jpg&thumbnail=660x&quality=80&type=jpg"/><br/></p><p>这次相对于上次相比,老年代的情况已经改善了,没有GC,说明大对象不存在了。</p><p>通过上面的分析跟优化,就满足GC的需求了,不需要再优化了。</p><p><h5>5 总结</h5></p><p>通过上面的分析及使用,VisualVM基本的使用以及如何利用VisualVM进行Java虚拟机优化相信你已经掌握了。</p> 

讯享网
小讯
上一篇 2025-04-30 23:26
下一篇 2025-05-26 14:48

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/172069.html