Java 性能方法论

Java 性能工作的正确顺序:定义指标、复现、剖析、改动、回归,避免过早优化。

#type / concept #status / growing #tech / dev #resource / java

[!info] 关联笔记

Java 性能方法论

这个概念为什么出现

“感觉慢”不能指导改代码。Java 有 JIT、GC、预热,错误基准会指向错误热点。方法论比某个收集器参数更重要。

[!abstract] 一句话理解 先定义用户指标与 SLO,再稳定复现,用剖析找热点,小步改动并回归;禁止一次 System.nanoTime 包装的伪基准下结论。

最小可观察示例

场景:对比两种拼接在错误基准下的误导(教学)

public class BadBenchmark {
    static String plus() {
        String s = "";
        for (int i = 0; i < 1000; i++) s += i;
        return s;
    }
    static String builder() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 1000; i++) sb.append(i);
        return sb.toString();
    }
    public static void main(String[] args) {
        long t1 = System.nanoTime();
        plus();
        long t2 = System.nanoTime();
        builder();
        long t3 = System.nanoTime();
        System.out.println("plusNs=" + (t2 - t1));
        System.out.println("builderNs=" + (t3 - t2));
        System.out.println("note=not-a-real-benchmark");
    }
}
javac BadBenchmark.java && java BadBenchmark

期望:打印两段耗时,并明确这不是科学基准(无预热、无迭代统计、JIT 未稳定)。

结合场景再看三个关注点

  1. 预热与多轮统计必要。
  2. JMH 才是微基准常用框架。
  3. 系统级指标(延迟分位、吞吐、错误率)优先于微基准。

核心概念与准确模型

1. 工作流

指标 → 复现 → 剖析(JFR/采样)→ 假设 → 改动 → 回归

2. 常见热点

分配过多、锁竞争、IO、错误缓存、正则、日志

3. 工具

JFR、async-profiler、JMH、指标系统

边界情况与反直觉行为

  1. 开发机与生产硬件差异。
  2. GC 停顿表现为“接口毛刺”。
  3. 优化可读性崩溃却只换 2% → 不值得。

常见误区

[!warning] 常见误区:先改代码再想指标 没有基线就没有优化。

工程实践

  1. SLO/SLA 写清。
  2. 负载测试贴近真实。
  3. 每次只改一类变量。
  4. 把剖析火焰图留档。

本节总结

  • 方法论 > 玄学参数
  • 测量与回归
  • 微基准慎用

自测题

  1. 为什么需要预热?
  2. 延迟看平均值够吗?
参考答案
  1. JIT 与缓存升温会改变稳态性能。
  2. 不够;应看分位数(P95/P99)与错误率。

延伸阅读与资料来源

资料类型支撑内容
JMH工具微基准
JDK Flight Recorder官方剖析
创建于 2026/7/15 更新于 2026/7/15