鲲鹏社区首页
中文
注册
开发者
基于DevKit Java性能分析工具的调优实践——G1巨型对象触发GC问题

基于DevKit Java性能分析工具的调优实践——G1巨型对象触发GC问题

DevKitjavajdk性能调优

发表于 2025/12/29

0

1 调优概述

鲲鹏DevKit是一款提供涵盖迁移、测试、性能调优及系统诊断等各环节的开发使能工具集。其中,DevKit Java性能分析工具是针对基于鲲鹏的服务器上运行的Java程序的性能分析和优化工具,能图形化显示Java程序的堆、线程、锁、垃圾回收等信息,收集热点函数、定位程序瓶颈点,帮助用户采取针对性优化。本文使用Java性能优化工具对运行中的Java程序进行在线分析和采样分析,找到程序中的G1巨型对象触发GC问题,并根据分析结果进行优化修改,从而实现Java程序最佳运行。

2 环境要求

项目

说明

服务器

TaiShan 200 服务器(型号2280

CPU

Kunpeng 920

OS

CentOS 7.6

调优工具

Kunpeng DevKit Java性能分析工具

3 前提条件

  1. 服务器和操作系统正常运行。
  2. PC端已经安装SSH远程登录工具
  3. 需要优化的Java程序

4 调优思路

  1. 使用Java性能优化工具对Java进程进行在线分析;
  2. 使用Java性能优化工具对Java进程进行采样分析
  3. 针对性能的瓶颈点进行性能优化;
  4. 观察优化后的Java程序,判断问题是否解决

5 调优过程

5.1 对程序进行在线分析,切换到GC页签

发现有些GC原因是巨型对象的分配造成的

image.png

5.2 对程序进行采样分析,切到GC页签

会得到一份优化建议报告

image.png

image.png


5.3      采样分析切换到 内存-->老年代对象页签

在某些情况下,如果巨型对象的生命周期比较长,则在该页签下可以采集到对象的相关信息,也会得到一份报告,可以得知巨型对象的具体信息

image.png

image.png

根据相关信息,可以得出结论采集的巨型对象是在同一个线程中创建的,巨型对象为2Mib 大小的 byte[],可以根据堆栈搜索代码,看看具体的逻辑。

5.4 在线分析执行内存转储

如果通过采样分析不能直接采集到巨型对象,可以通过得知的 region 大小,我们从堆转储分析中找找相应的线索

5.4.1 步骤一:直方图中找堆占用较多的嫌疑类

image.png

5.4.2 步骤二:查看每个嫌疑类的所有对象

发现 频繁分配了 byte[],大小为 2Mib,符合巨型对象要求,继续定位

5.4.3 步骤三:支配树查找线索

支配树中发现一个线程保留堆大小跟直方图中byte[]的保留堆大小差不多

image.png

展开发现 这个线程中有个List 持有创建的巨型对象

image.png

查看byte[]GC Roots的路径

image.png

5.5      程序代码定位

根据采样分析和堆转储的分析,查找程序中的相关代码,本案例的demo不复杂,根据采样分析提供的类名: DockerTestController ,巨像对象为byte[],  分配大小为2Mib,List持有巨型对象等线索,直接找到了具体的代码

5.6      优化后的 Java程序

demo通过设置调大 region 大小的方式解决该问题image.png

6 实践总结

本次实践中,通过采样分析和堆转储分析定位代码中具体巨型对象分配的位置,通过调大region 大小解决。但是在实际的业务中,优先建议调整代码逻辑去解决问题,尽量避免分配巨型对象,从而减轻jvm的压力。 如果发现默认的region大小,不符合程序的体量,那么可以根据实际情况适当调大region大小。

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

本页内容