易君召
发布于 2026-09-08 / 作者:易君召 / 6 阅读
0

Java 项目提升执行效率实战总结

代码写法、JVM、集合 IO、并发、数据库、架构算法六个维度整理,全部是项目可落地的优化点,不空谈理论。

一、基础代码层面优化

1. 字符串处理

  1. 循环拼接字符串禁止直接使用+,大量循环用StringBuilder;少量简单拼接编译器会自动优化为 StringBuilder。

// 差
String s = "";
for(int i=0;i<1000;i++) s += i;

// 好
StringBuilder sb = new StringBuilder();
for(int i=0;i<1000;i++) sb.append(i);
  1. String.substring()旧版本会持有原 char 数组,大字符串截取建议 new String 包装;Java9 + 内部改用 byte [] 无此问题。

  2. 尽量用equals常量放前面:"abc".equals(str)避免空指针同时无性能损耗。

2. 循环优化

  1. 减少循环内计算,把方法调用、属性提取提到循环外

// 差
for(int i=0;i<list.size();i++){}

// 好
int len = list.size();
for(int i=0;i<len;i++){}

注:现代 JIT 会自动做提升,但多层嵌套循环手动提取收益更高。

  1. 嵌套循环:小循环放外层,大循环放内层,减少循环切换开销。

  2. 避免循环内创建对象,对象尽量在外层 new,循环内复用。

  3. for‑each 底层迭代器,遍历 ArrayList 优先普通 for;LinkedList 不要用普通 for(随机访问 O (n))。

3. 对象与基本类型

  1. 优先使用基本类型int/long,避免包装类Integer/Long,减少自动装箱拆箱。

// 拆箱产生额外开销
Integer a = 1000;
int b = a;
  1. 局部变量尽量缩小作用域,利于 JIT 逃逸分析;局部对象有可能被栈上分配,不进堆。

  2. 不要创建无用对象:方法内不要 new 临时对象,能复用就复用;避免new Integer(xxx)构造器,用Integer.valueOf()走缓存。

  3. 尽量使用对象池复用重对象:连接、线程、大缓冲区,不要频繁 new 销毁。

二、集合框架性能优化

场景

推荐

不推荐

随机访问、遍历

ArrayList

LinkedList

频繁头尾增删

ArrayDeque

LinkedList

HashMap 初始化

指定初始容量 new HashMap<>(size * 2)

不指定容量,频繁扩容 rehash

去重

HashSet

循环 List 判断 contains

  1. HashMap 初始容量预估:expectedSize / loadFactor,默认负载因子 0.75,避免反复扩容复制数组。

  2. contains():ArrayList 是 O (n),HashSet 是 O (1),大数据量判断存在性务必用 HashSet。

  3. 遍历 Map 优先entrySet(),不要keySet()再 get,减少二次查询。

// 高效
for(Map.Entry<String,Object> entry : map.entrySet()){
    String k = entry.getKey();
    Object v = entry.getValue();
}
  1. 集合遍历中不要做 remove,用迭代器iterator.remove()或者removeIf()

  2. 大集合用完及时置 null 帮助 GC,局部变量方法结束自动失效。

三、IO & 资源

  1. IO 一定用缓冲:文件、网络流套BufferedReader/BufferedInputStream,减少系统调用。

  2. 使用 try‑with‑resources 自动关闭流,杜绝资源泄漏,泄漏会直接导致性能越来越差。

try(BufferedReader br = Files.newBufferedReader(path)){
}
  1. 文件读取:不要一次性读全部大文件到内存,按行 / 分块流式处理。

  2. 序列化:Java 原生Serializable性能差,大数据优先使用 JSON、Protobuf、Hessian 等。

四、并发编程优化

  1. 优先使用 J.U.C 工具类,少手写synchronized

  2. 锁粒度尽量小:锁只包裹竞争代码,不要锁整个大方法;缩小同步块范围。

  3. 读多写少场景:ReentrantReadWriteLock;无锁优先AtomicXXX;高并发计数用LongAdderAtomicLong性能更好。

  4. 线程池不要手动 new Thread,统一使用线程池;合理设置核心线程、队列、拒绝策略,避免无限队列 OOM。

  5. 避免不必要同步:只读数据不加锁;不可变对象final可以安全多线程访问。

  6. 减少上下文切换:不要大量创建销毁线程;避免空自旋;高并发减少锁争抢。

五、JVM 层面优化(运行效率)

  1. 善用逃逸分析:方法内部对象,如果不会逃逸出方法,JIT 可以栈上分配,减少 GC。

  2. 减少大对象:大于阈值直接进老年代,频繁大对象造成 FullGC。

  3. GC 调优:区分业务类型

  • 响应优先(接口服务):降低 STW,优先 G1/ZGC;

  • 吞吐量优先:ParallelGC。

  1. 避免内存泄漏:静态集合持有对象、未关闭流、线程池引用、ThreadLocal 未 remove。

ThreadLocal 用完必须 remove,否则内存泄漏。

  1. JIT:热点代码会被编译成本地机器码,不要写频繁只执行一次的复杂逻辑;循环内是 JIT 重点优化区域。

六、数据库 & RPC(绝大多数项目瓶颈在这里)

大部分 Java 慢不是 Java 代码慢,是 IO / 数据库慢。

  1. SQL 优化:索引、避免 select *、避免大表全表扫描,分页大数据不要 offset 分页,用主键游标分页。

  2. 数据库连接池:合理配置连接数,不要过大过小;连接用完归还。

  3. 批量操作:jdbc batch 批量 insert/update,不要循环单条提交。

  4. 缓存:热点数据加本地缓存 (Caffeine)、Redis 缓存,减少 DB 访问。

  5. RPC:减少远程调用次数,批量接口,不要循环调用远程接口。

  6. 慢查询监控,打印慢 SQL、慢接口日志。

七、算法与架构优化(收益最大)

  1. 算法复杂度优先:O (n²) 改成 O (n log n),比调 JVM 收益大得多。优先优化算法,再抠语法细节。

  2. 避免重复计算:结果缓存,备忘录模式。

  3. 异步化:非关键路径任务异步执行,MQ 解耦,主线程只处理核心逻辑。

  4. 分而治之:大任务分片处理,避免一次性加载全量数据到内存。

八、常见误区(不要瞎优化)

  1. 过早优化:没有压测、没有定位瓶颈就到处改代码。先定位瓶颈(Arthas、jstack、jmap、JProfiler),哪里慢优化哪里。

  2. 不要迷信小技巧:现代 JIT 编译器会做大量优化,很多教科书旧优化已经被 JIT 自动处理。

  3. 可读性优先:不要为了微小性能牺牲代码可维护性。

常用性能排查工具

  • Arthas:线上定位慢方法、热点方法、监控执行耗时

  • Jstack:线程栈,死锁、阻塞

  • Jmap:堆快照,内存泄漏、大对象

  • Jmeter / Gatling:压测接口


本文原创作者:易君召,详见:https://www.yijunzhao.cn/authors/yijunzhao,转载请注明出处。

原文链接 https://www.yijunzhao.cn/archives/java-project-execution-efficiency-practical-guide

欢迎访问 小易撩挨踢

https://www.yijunzhao.cn/