Java代码性能分析:在实践中寻找瓶颈

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Java代码性能分析:在实践中寻找瓶颈



每位Java开发者迟早都会遇到性能问题:应用程序运行缓慢、消耗过多内存或意外“卡死”。在这种情况下,性能分析是必不可少的。在本文中,我们将探讨如何利用现代性能分析工具在实践中找到Java代码中的瓶颈。



什么是性能分析,为什么需要它?



性能分析(profiling)是一种动态的程序分析,用于收集程序运行时的数据:CPU负载、内存使用、方法执行时间、创建的对象数量以及线程信息。与日志记录不同,性能分析能够精确地呈现“瓶颈”所在,无需手动设置计时器。



性能分析的主要类型:

  • CPU性能分析 — 确定哪些方法消耗了最多的处理器时间。
  • 内存性能分析 — 发现内存泄漏、对象创建频率以及垃圾回收器(GC)的工作情况。
  • 线程性能分析 — 分析锁、死锁和线程状态。


Java性能分析工具



我们来介绍三种最流行的工具,它们能帮助您找到瓶颈。



1. VisualVM

免费工具,包含在JDK中。非常适合快速分析正在运行的应用程序。可以监控CPU、内存、线程,甚至执行堆转储(heap dump)。

// 从命令行启动VisualVMjvisualvm.exe


2. JProfiler

商业性能分析器,功能强大:详细分析CPU、内存、JDBC、JPA和SQL查询。非常适合企业级应用。



3. Java Flight Recorder (JFR) + JDK Mission Control

内置于JVM的工具(从Java 11开始可用)。收集底层事件,对性能影响极小。推荐用于生产环境。

// 录制JFR 60秒jcmd <PID> JFR.start duration=60s filename=recording.jfr


实践示例:寻找瓶颈



假设我们有一个处理用户列表并生成报告的应用程序。它运行缓慢。我们编写一个简单的测试代码,并使用VisualVM对其进行分析。



步骤 1. 准备代码

import java.util.ArrayList;import java.util.List;

public class SlowApp { public static void main(String[] args) { List<String> users = new ArrayList<>(); for (int i = 0; i < 100000; i++) { users.add("User" + i); } processUsers(users); }

public static void processUsers(List<String> users) { for (String user : users) { String report = generateReport(user); // 模拟保存 System.out.println(report.length()); } }

public static String generateReport(String user) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < 1000; i++) { sb.append(user).append(" - data ").append(i).append(""); } return sb.toString(); }}


步骤 2. 启动性能分析

启动应用程序并打开VisualVM。在左侧面板中选择进程,切换到“Profiler”选项卡,然后点击“CPU”开始性能分析。



步骤 3. 分析结果

停止性能分析后,您将看到一个按耗时排序的方法表格。在我们的示例中,generateReport方法将排在首位——由于循环中的字符串拼接,它消耗了超过90%的CPU时间。



步骤 4. 优化

将StringBuilder替换为预分配的缓冲区:


                
                

博客

书籍推荐