我让GitHub Copilot分析Java应用,它发现了堆大小配置缺陷并主动提出修复
我构建了一个扩展,旨在整合Java工作负载运行与性能测量的完整闭环,使其能够在代理式AI时代中被一些开发者视为新“开发环境”的地方使用:GitHub Copilot应用。
构想:Copilot驱动的性能剖析
这个扩展名为JVM Pulse,下面是展示一次真实运行的完整过程。JVM Pulse是GitHub Copilot应用的一个画布扩展。它没有硬编码如何构建或运行Java项目,也不需要用户提供具体细节。你只需点击“Run analysis”,Copilot就会完成项目相关的工作:它会检测你的构建工具和JDK,编写或编译一个具有代表性的工作负载,并使用正确的标志(统一的GC日志记录和设置为profile的JFR记录)来启动它。
然后,生成的数据会通过微软的GCToolkit和JDK的jfr命令行工具进行处理,最终全部呈现在一个交互式仪表盘中:吞吐量、暂停百分位数、堆占用率、分配压力、热点方法、锁竞争、安全点、I/O等数据一目了然。
这次演示中,我将其指向了一个JairoSVG渲染基准测试:43个示例SVG文件,循环执行“解析+渲染+PNG编码”操作,耗时约25秒,堆固定在256M,使用G1GC(JDK 25)。 [LOADING...] 运行分析——Copilot将运行并对应用进行性能剖析
步骤 1 —— Copilot运行完毕,并展示了它所做的具体操作
在AI工具中,我最看重的就是它能透明地展示自己做了什么。JVM Pulse会记录精确的启动命令,包括每一个JVM标志。在完成5,633次渲染后,GC日志和JFR记录被捕获,仪表盘显示在聊天界面旁边。 [LOADING...]
步骤 2 —— 用通俗语言给出的结论
仪表盘并非直接显示一堆数字,而是首先进行健康评估:
- 吞吐量 99.72% —— GC 不是瓶颈
- p99暂停 7.8 ms —— 暂停问题不值一提
- 分配速率 156 MB/s,总计约 4.3 GB —— 被标记为偏高,“进一步优化的主要杠杆”
- 堆峰值 243 MB(共 256 MB) —— 基本占满
[LOADING...] 仪表盘已填充数据
传统的性能剖析工具会显示p99,然后让你自己得出结论。而这个工具直接告诉你该往哪里看:暂停没问题,分配是你的杠杆。
步骤 3 —— 一键将数据交回Copilot
一个“用AI分析”按钮,将完整的gc-jfr-report.json和原始的jfr-all-views.txt文件连同预设的提示一起送回Copilot会话:
[LOADING...] “用AI分析”按钮会触发一个包含性能剖析数据的提示。
步骤 4 —— 给出根本原因,而非简单摘要
到这里,它就不再像个玩具了。Copilot读取了按分配点分类的视图,并回复:
表面健康,底层存在一个结构性问题。
结构性问题:在近乎占满的堆上进行了大对象分配。在256M堆下,G1选择1M的区域大小,因此大对象阈值是512KB。支撑BufferedImages的int[]光栅超过了这个阈值,所以堆中约43%是大对象区域,23.4%的GC是由G1_HUMONGOUS_ALLOCATION触发的。每个大光栅都会强制进行一次回收。 [LOADING...] GC评估
步骤 5 —— 带分析依据的优化建议
调优建议以表格形式呈现,每个标志都关联到它所改善的指标: [LOADING...] JVM配置建议
至关重要的是,它将配置修复与持久的代码修复区分开来:仅BufferedImage.<init>就占了约35%的总分配。每次渲染都分配了一个全新的光栅。真正的优化点在于使用一个池化/复用的临时图像,这样无论堆大小如何,都能从根本上消除int[]造成的43.5%的数据流转。 [LOADING...] 分配和代码热点分析
步骤 6 —— 它主动提出运行实验
Copilot没有只留下一张待办清单,而是提出了下一步:
“使用 -Xmx1g -XX:G1HeapRegionSize=4m 重新运行相同的25秒工作负载……你想现在运行实验#1,还是先实现缓冲区重用?”
分析 → 假设 → 实验,全都在一个地方完成。 [LOADING...] 结论与后续实验
步骤 7 —— 证明优化生效
每次运行都会被保存。点击“比较”,选择前一次运行作为基线,JVM Pulse会将两者并排对比差异。吞吐量、暂停、分配、堆、GC事件,甚至还包括两次启动命令的逐标志对比。这样你不仅仅相信优化生效了,而是能看到它确实有效。
这构成了完整的科学闭环:假设、运行、测量、比较——一切都在你编码的工具内部完成。
为什么这很重要
这里涉及的各个单独部分并不是新东西。GCToolkit可以解析GC日志。JFR一直拥有这些数据。真正新颖的是消除了从“这里有遥测数据”到“这里是需要修改的内容”之间的转换成本,并将整个循环保持在一个界面上,由智能体驱动,既能读取数据,又能执行操作。
JVM Pulse是开源项目(MIT许可)。如果你是用Java的开发者,并且曾经在基准测试、日志解析器和标志参考文档之间来回切换,我非常希望你来试试看。
👉 https://github.com/brunoborges/jvm-pulse
基于Microsoft GCToolkit、JDK的jfr命令行工具以及GitHub Copilot画布扩展API构建,并利用了GitHub Copilot SDK实现AI集成。 即使没有GitHub Copilot订阅,也可以使用GitHub Copilot应用,同时支持自带模型(BYOK)。
文章《我让GitHub Copilot对Java应用进行性能剖析。它发现了我堆大小设置中的Bug,并主动提出修复》最初发表于foojay。