[调优工具] 【Hyper Tuner调优实践 03】基于Java性能分析工具的内存泄露调优实践

1      调优概述

华为鲲鹏性能优化工具是一款针对鲲鹏平台的性能调优工具,包含系统性能优化工具和Java性能优化工具。本文使用Java性能优化工具对运行中的Java程序进行了基于ProfilingGC和内存分析、结合Sampling分析,找到程序问题,并根据分析结果进行优化修改,从而实现Java程序最佳运行。

2      环境要求

项目

说明

服务器

TaiShan 200 服务器(型号2280

CPU

鲲鹏920 4826处理器

OS

CentOS 7.6

应用

Java应用程序

性能分析工具

Hyper Tuner 2.2.T2.SPC100

3      前提条件

1.    服务器和操作系统正常运行。

2.    PC端已经安装SSH远程登录工具

3.    需要优化的Java程序

4      调优思路

1、  检查Java程序的基础参数;

2、  使用Java性能优化工具对Java进程进行GC分析以及内存分析;

3、  使用Java性能优化工具对Java进程进行Sampling分析

4、  针对性能的瓶颈点进行性能优化;

5、  观察优化后的Java程序,判断性能是否提升

5      调优过程

5.1      检查Java程序的基础参数

步骤1     登录Java性能优化工具

步骤2     创建Guardian (说明:部署的需要优化的Java进程的服务器)

image02.png


步骤3     启动Profiling分析

获取到的Java程序的基础参数如下图:只配置最大堆大小可继续通过工具其他功能分析

image03.png


5.2      查看Profiling概览

概览分析:通过概览功能页面查看Java进程发现内存占用很高、GC活动也频繁

image52.png


5.3      查看Profiling GC

步骤1     点击页面上方的【GC】页签

步骤2     查看GC的活动详情

GC分析:发现在几分钟内多次出现old GC,后续old GC频繁

old GC 频繁的原因分析:

image531.png


image532.png


5.4      查看Profiling内存转储

Java进程的内存在old GC之后回收的内存较少,且频繁GC,继续使用工具其他功能分析

步骤1     页面上方的【内存转储】页签

步骤2     等待执行内存转储的结果

内存转储分析:下图为内存转储的【直方图】,展示了Java进程中堆内存分配,可以发现第一行的Object[] 与其他数据的浅堆大小不在一个数量级,此时需要结合支配树继续分析

image541.png


 

支配树分析:下图中的第一行非常直观的可以发现该ScheduleTask类的浅堆大小占据了整个堆的98.27%,继续查看该类的下级支配数据,最终发现该类支配了大量的Object[]类,Object[]类下支配最多的即Student

image542.pngimage543.png



5.5      优化 Java程序

分析:

通过上述四步骤的Profiling分析,可以发现堆内存被大量的ScheduleTask类支配的Student类所占据,因此回归Java程序本身发现该ScheduleTask类是一个作为缓存功能的类,自己检视代码发现该类使用的HashMap作为缓存对象,在构建代码时忽略了缓存的过期时间,导致历史的数据一直在该缓存对象中导致内存泄露,GC无法回收对象。

优化:

       优化代码,加入缓存过期策略;

5.6      优化后的 Java程序

优化后的程序通过概览页即可发现内存使用正常、GC活动正常

image56.png


6      实践总结

本次实践中,对一Java程序进行了性能分析,通过Profiling GC分析和内存转储分析发现了程序中的内存泄漏点,进而优化程序中的内存泄漏点达到优化程序性能的目的,解决了程序中内存持续占满且频繁old GC的问题。

在进行其他程序调优时,需要根据华为鲲鹏性能优化工具采集分析的实际结果和对应的优化建议进行调优操作。具体的调优思路可以参考本次实践。