AI 助力 Dragonwell Native 加速:10 倍性能提升机会的自动发现实践
每一个性能优化工程师的苦恼莫过于练就了一身“绝世武功”却苦于找不到真正的敌人——性能瓶颈。现实中大部分时间往往耗费在定位瓶颈和构建合适的性能测试上而一旦找准问题修复反而常常迅速完成。因此精准识别性能瓶颈才是高效性能优化的核心痛点。那么AI 能否帮助我们自动寻找这些隐藏的瓶颈并指导实施精准的性能提升带着这一问题我们开发了一个通用的 AI 驱动性能分析系统并以 Apache Spark 作为典型案例进行验证。评估显示方法是有效的AI 发现的可优化函数通过 Dragonwell 的 Native 加速技术应用后在 JMH 测试中最高实现了 10 倍的性能提升在 TPC-DS 端到端测试中结合原有优化使整体性能最高提升了 9.69%。Spark 的 Native 优化函数已经发布在最新的 Dragonwell 版本中。性能瓶颈分析的传统流程及其挑战目前开发者通常遵循以下三步流程来分析性能瓶颈采集热点数据在 Java 项目中常用 AsyncProfiler 等工具采集运行时数据生成火焰图和 JFRJava Flight Recorder格式的二进制文件。开发者依赖经验从火焰图中识别潜在的瓶颈函数。代码审查回到源代码中检查该函数为何执行耗时是否存在优化空间。验证或回退若发现优化点则实施并验证否则返回火焰图寻找下一个候选。这一流程高度依赖人工经验且极其耗时。于是我们不禁思考能否将火焰图数据与源代码直接交给 AI让它自动筛选出值得优化的候选函数然而要评估 AI 是否胜任必须先看清问题的规模。以 Spark 4.0 运行 TPC-DS 基准测试为例优化分析面临的问题空间极为庞大2254 个 JFR 火焰图文件TPC-DS 包含 103 个查询在 3 个节点上运行每个节点启动多个进程每个进程生成一个 JFR 文件总计为 2254 个每个文件包含约 8 万个函数采样点。28 万行代码Spark 4.0 代码库包含约 27 万行 Scala 和 1 万行 Java 代码需从中定位瓶颈函数及其上下文。函数优化潜力判断对每个候选函数需要判断是否具备实际优化价值。在这个复杂的问题空间中第三项任务——判断函数是否可优化——正是 AI 的强项第二项理解代码上下文AI 也能较好应对但第一项从海量二进制数据中提取关键信息则远非当前大模型所长。因此我们必须设计一个扬长避短的工作流让 AI 专注于它最擅长的部分同时借助传统工具处理结构化、高吞吐的数据处理任务。工作流设计传统工具与 AI 的协同架构为此我们构建了如下图所示的智能性能分析优化系统。系统以任意 Java/Scala 项目的代码仓库和 JFR 文件目录为输入输出一份结构化的优化分析报告。该系统的核心是一确定性强、流转清晰的分析工作流。我们选择用程序而非 Skill 来实现这一流程原因在于每一步的触发条件明确、逻辑固定使用代码实现不仅更快、更稳定还能避免不必要的大模型 token 消耗。工具的强项快速、稳定、可靠AI 虽强大但并非万能。只有与传统工具深度协作才能使其聚焦核心任务发挥最大效能。为此我们开发了两个关键协作工具供 AI 调用JFR 热点分析工具将成百上千个 JFR 文件聚合生成全局热度摘要提炼出 Top N 热点函数列表使大模型无需处理原始二进制数据。基于 AST 的函数查询工具通过解析源代码构建抽象语法树AST精准定位并返回目标函数的完整定义及上下文相比简单的 grep 搜索更准确、更健壮。这两个工具有效屏蔽了 AI 不擅长的基础数据处理和模糊文本匹配问题减少了 AI 工作时的上下文数量使其能够保持在优化分析上关注度。这种“各司其职”的协作理念贯穿整个系统设计。在初期我们曾尝试将所有任务交由 AI 完成但很快发现其在某些结构化任务上表现不稳定。例如判断一个函数是否为 synchronized 时AI 会错误地在文件中全局搜索关键字导致误判。于是我们将此类任务剥离出来用确定性代码实现显著提升了系统的准确性和可靠性。AI 的强项语义理解与意图识别-以 Native 加速优化为例Dragonwell 21 中引入了一项名为“Native 加速优化”的技术可使特定函数性能提升高达 10 倍。其原理是绕过 JVM 的部分开销直接调用高度优化的本地汇编实现。但这也带来了严格的安全约束只有满足特定条件的函数才能安全启用该优化典型的如无逃逸不能通过返回值或设置全局变量等方式将内部新创建的实例逃逸出函数的作用范围这样会导致 Native 内存与 JVM 内存之间的复杂交互是 Native 加速优化没有处理的。无异常分析函数不能抛出异常Native 加速优化没有实现异常处理机制。在安全约束之外函数中也需要存在优化机会才具备实施的必要性如函数的汇编代码不能过少如果函数的汇编代码指令非常少那么 JDK 的 JIT 编译的代码就足够好了。函数是计算密集型计算密集型的编译优化空间较大IO 操作、对象分配操作等没有优化空间。存在其他优化机会例如消除条件跳转、采用向量指令等保持函数输入输出不变但是采用更快的语义优化的机会。传统的静态分析很难实现以上的安全性和必要性检查而依靠人工执行这些检查更是如同大海捞针但是对这几点的分析却正是大模型的强项。我们为此设计了三个专用 AI Agent逃逸分析 Agent相比复杂的传统指针分析大模型能基于代码语义快速判断对象是否逃逸实现简单且效果良好。异常分析 Agent异常分析的难点并不在于检测代码中是否存在显式的 throw而是判断抛异常的行为是否位于不可达的路径上使得事实上不会抛出异常。比如以下代码中第 15 行的 getSize 函数是否会抛出异常呢从表面上看16 行的 switch 语句的 default 情况就会抛出异常。但是仔细分析可以看到在生产环境中第 16 行的 getUaoSize 只可能返回 4 或者 8而不可能是别的值所以 default 情况是不可达的。传统的静态分析很难分析出这段代码的意图但是大模型可以理解代码意图并且从上下文中分析得到不会抛出异常的答案。private staticfinalint UAO_SIZE Platform.unaligned() ? 4 : 8; privatestaticint TEST_UAO_SIZE 0; // used for test only public static void setUaoSize(int size) { assert size 0 || size 4 || size 8; TEST_UAO_SIZE size; } public static int getUaoSize() { return TEST_UAO_SIZE 0 ? UAO_SIZE : TEST_UAO_SIZE; } public static int getSize(Object object, long offset) { returnswitch (getUaoSize()) { case4 - Platform.getInt(object, offset); case8 - (int) Platform.getLong(object, offset); default - // checkstyle.off: RegexpSinglelineJava thrownew AssertionError(Illegal UAO_SIZE); // checkstyle.on: RegexpSinglelineJava }; }优化机会分析 Agent大模型不仅能够发现优化机会还能够联系上下文挖掘出人类容易忽略的问题。例如对于以下函数我们曾经也人工看过但并没有仔细观察过第 1 到 20 行的数组。因为面对这么复杂的数据人的本能是逃避跳过。但是大模型告诉我们只要把这个数组中的 0 换成 1就可以将第 28 行的三元条件判断操作变成直接读数组中的元素从而实现优化。更进一步将 byte 数组改为 int 数组的话还能节省从 byte 到 int 的符号扩展操作开销。private staticbyte[] bytesOfCodePointInUTF8 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00..0x0F 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10..0x1F 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20..0x2F 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30..0x3F 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40..0x4F 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50..0x5F 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60..0x6F 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70..0x7F // Continuation bytes cannot appear as the first byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x80..0x8F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x90..0x9F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xA0..0xAF 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xB0..0xBF 0, 0, // 0xC0..0xC1 - disallowed in UTF-8 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xC2..0xCF 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xD0..0xDF 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xE0..0xEF 4, 4, 4, 4, 4, // 0xF0..0xF4 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0// 0xF5..0xFF - disallowed in UTF-8 }; ... public static int numBytesForFirstByte(final byte b) { finalint offset b 0xFF; byte numBytes bytesOfCodePointInUTF8[offset]; return (numBytes 0) ? 1: numBytes; // Skip the first byte disallowed in UTF-8 }通过这些 AI Agent 的协作工作系统能够高效、准确地评估函数是否适合应用 Native 加速优化。效果从函数到端到端的显著提升性能优化分析系统以 Spark 代码仓和 2000 的 JFR 文件为输入对最热的 400 个函数200 个 Spark 函数200 个 JDK 函数进行分析耗时 3 个小时 21 分钟成功识别出 34 个具有 Native 加速优化潜力的函数。出于开发成本考虑我们选取了其中的两个典型函数进行优化在 Dragonwell 21 上的测试效果如下线程热度在单个线程中的执行热度。有的函数全局热度很高但是线程热度低说明函数执行时间被大量的线程并行稀释。这种函数不是性能瓶颈。进程热度在单个进程中的热度对于 TPCDS 测试就是单个 query 中的热度。全局热度将所有 JFR 文件合并起来后的全局热度对于 TPCDS 测试就是在全部 query 整体中的热度。在 TPC-DS 全部 query 的端到端测试中优化成果显著Dragonwell 21 Native 加速优化相比 OpenJDK 21 提升 5.7%其中 AI 发现优化贡献约2.2%。Dragonwell 11 Native 加速优化 相比 OpenJDK 11 提升 9.69%其中 AI 发现优化贡献约4%。Dragonwell 8 Native 加速优化 相比 OpenJDK 8 提升 6.11%其中 AI 发现优化贡献约 2.5%。端到端测试环境为节点一个 master三个 worker。CPUAMD EPYC 9T24master 8 核worker 32 核。内存master 32Gworker 128G。下一步深化 AI 能力与自动化闭环基于当前成果我们计划从以下方向持续推进拓展优化分析维度开发更多类型的 AI Agent覆盖更广泛的优化场景。例如对比不同厂商的 JDK 在相同负载下的性能差异为 Dragonwell 自动发现编译优化机会探索限制条件更宽松的 Java 代码优化机会只需修改 Java 代码即可实现优化。构建端到端自动化流水线将性能采样、热点识别、AI 分析、优化建议生成、自动打补丁、回归测试与效果验证等环节串联起来形成“分析-优化-验证”闭环。未来目标是实现“一键性能调优”大幅降低人工介入成本。总结本文实践揭示了两个关键洞见第一AI 与传统工具与协同而非替代。 性能优化是一个复杂系统工程既有结构化、高吞吐的数据处理任务如 JFR 聚合、AST 解析也有高度依赖语义理解的判断任务如逃逸分析、异常可达性。将前者交由高效稳定的传统工具处理后者交由 AI 专注分析才能实现效率与准确性的双赢。这不是“把所有事情扔给 AI”而是“让每个组件做它最擅长的事”。第二AI 在性能优化分析中具有良好效果。 无论是识别 Native 加速机会还是挖掘隐藏的代码优化点AI 都展现出超越人工的洞察力。当前系统虽已取得显著收益但仍有大量手动环节。下一步应着力打通全流程自动化让 AI 驱动的性能优化从“辅助工具”进化为“标准基础设施”。在 AI 的辅助下Dragonwell 21 所特有的优化能力得到了放大将优化范围扩展到了原先依靠人力难以抵达的位置取得了更好的优化效果。文中介绍的 Spark Native 优化函数已经发布在了最新的 Dragonwell21、11 和 8 的版本中Alibaba_Dragonwell_Extended_21.0.10.0.107、Alibaba_Dragonwell_Extended_11.0.30.27.7、Alibaba_Dragonwell_Extended_8.28.27具体用法请参考https://github.com/dragonwell-project/dragonwell21/wiki/Dragonwell-21-AI%E2%80%90Extension-%E7%94%A8%E6%88%B7%E6%8C%87%E5%8D%97