---
title: 调优过程
description: "- 已安装鲲鹏DevKit。"
url: https://www.hikunpeng.com/document/detail/zh/kunpengdevps/profiler/demo/kunpengjptmlpractice_21_0005.html
sourcePath: /source/zh/kunpengdevps/profiler/demo/kunpengjptmlpractice_21_0005.html
indexId: 3b183fb4f938eb498e8a46ddd007c73a62aa7873a7e870c262e8d265ac6cc57271
---
# 调优过程

#### 前提条件

- 已安装鲲鹏DevKit。
- 服务器和操作系统正常运行。
- PC端已经安装SSH远程登录工具。
- 准备需要优化的Java程序（  demo(https://github.com/kunpengcompute/devkitdemo/tree/main/Hyper_tuner/testdemo/基于java性能分析工具的内存泄漏调优实践)
）并在目标服务器上启动。


#### 准备工作

1. 登录Java性能分析工具。
2. 添加目标服务器（待分析的Java进程所在服务器）。
  图1 添加目标环境

3. 启动在线分析功能。
  图2 启动在线分析


#### 在线分析

1. 概览页签查看进程整体情况。
  图3 概览

  通过概览页面发现程序的堆使用情况在一段时间内不断升高，同时GC也比较频繁，但是堆却没有明显地被释放，可能存在内存泄漏。

2. GC页签查看GC详情。
  图4 GC页签

  分析发现GC比较频繁的有YoungGC和OldGC，但是每次GC回收的内存可以忽略不计，甚至根本没有回收任何内存，此现象说明内存泄漏的可能性很大。

3. 内存页签查看内存详情。
  图5 内存页签

  在内存转储页签下单击“执行内存转储”按钮生成堆转储文件，为了方便查看堆的变化，单击按钮保存当前页面的快照，再次单击“执行内存转储”可以生成多次堆转储文件。

4. 再次生成内存堆转储文件。
  图6 结果比较

  通过生成两次堆转储文件发现TestMemoryLeak$Person应该是自定义的类，内存占用情况较多，并且随着时间呈上升趋势，需要重点观察。

  单击按钮，再次生成快照，利用快照功能提供的比较操作，查看两个堆转储文件中相同类实例与保留堆的变化情况，通过比较发现TestMemoryLeak$Person实例与保留堆是明显上升的趋势。

5. 在“显示类型”下拉菜单中选择“支配树”，切换到支配树模式，以树形结构显示内存转储信息。
  图7 支配树视图

  切换到支配树模式，发现TestMemoryLeak类的保留堆占总堆的比例高达99%，继续向下点开支配树发现大部分对象是TestMemoryLeak$Person持有的byte[]，正好可以与直方图中byte[]占较多可以对应上。

6. 结果分析。
  图8 代码片段 经过直方图与支配树的分析，TestMemoryLeak$Person类对应的实例有内存泄漏嫌疑，根据支配树提供的内容应该是HashSet实例持有TestMemoryLeak$Person对象，接下来可以搜索代码中的相关项看看。本案例中的demo程序比较简单，直接搜索TestMemoryLeak类可以发现的确存在内存泄漏点，一个线程不断地往hashSet和hashSetPerson两个静态对象添加Person实例，并且没有清除的逻辑，导致出现内存泄漏。


#### 采样分析

对目标程序进行采样分析，建议进行多次采样，采样时间相对长一点。

1. 启动采样分析。
  图9 配置采样分析参数

2. 查看采样分析结果。
  图10 采样分析结果
