Java 全方位性能优化方法论
整体分为五层代码层 → JVM 层 → 并发层 → 框架中间件层 → 架构层附带常见坑、优化手段、排查工具。一、代码层面优化开发日常最容易落地1. 对象创建与内存避免循环内频繁创建对象java运行// 不推荐 for(int i0; i1000; i){ String s new String(test); } // 推荐循环外复用 String s new String(test); for(int i0; i1000; i){}优先使用基本类型而非包装类intInteger减少自动装箱拆箱。字符串拼接循环拼接使用StringBuilder禁止会频繁生成新对象少量常量拼接编译器自动优化直接无影响集合选型随机查询ArrayList频繁头尾增删LinkedList线程安全不要无脑Vector/HashTable优先ConcurrentHashMap预估集合容量指定初始 capacity减少扩容拷贝java运行// 推荐避免多次扩容 ListString list new ArrayList(1024);数组优于集合大数据批量场景优先数组。2. 循环与条件循环内不要重复计算长度for(int i0;iarr.length;i)底层优化但自定义方法调用建议提前提取多重循环外层短、内层长提升缓存命中率减少循环内复杂计算、IO、数据库查询3. IO 相关使用缓冲流BufferedInputStream/BufferedReader减少系统调用文件读写尽量批量不要逐字节读写流必须try-with-resources自动关闭避免句柄泄漏二、JVM 调优GC、内存模型1. 内存区域基础堆新生代 (Eden/S0/S1) 老年代元空间 (Metaspace) 核心目标降低 GC 频率、减少 STW 停顿2. GC 收集器选型JDK8 ~ JDK17表格JDK 版本推荐收集器特点JDK8G1平衡吞吐量与停顿默认备选JDK11ZGC / Shenandoah低延迟毫秒级 STW大堆首选生产杜绝Serial、Parallel Old 用于高并发服务。3. 关键参数思路堆大小Xms Xmx防止运行期堆扩容消耗性能不要无限加大堆堆越大Full GC 停顿越长新生代比例G1 不需要手动设置-XX:NewRatio交由自适应调节元空间-XX:MaxMetaspaceSize防止元空间持续膨胀 OOM开启 GC 日志用于事后分析plaintext-Xlog:gc*,gcheapdebug:filegc.log:utctime,level,tags4. JVM 常见问题频繁 Young GC短生命周期对象过多循环创建对象、临时 DTOFull GC 频繁内存泄漏、大对象直接进老年代、堆不足OOM堆溢出、元空间溢出、直接内存溢出、线程栈溢出5. 直接内存NIOByteBuffer.allocateDirect()使用堆外内存不受 - Xmx 限制使用完毕主动释放防止堆外内存泄漏。三、并发编程性能优化锁优化缩小锁范围锁粒度尽可能小优先乐观锁CASAtomic 系列、LongAdder synchronizedLongAdder高并发计数优于AtomicLong分段锁减少竞争避免锁嵌套防止死锁读写分离场景ReentrantReadWriteLock读多写少大幅提升吞吐线程池重中之重禁止手动 new Thread ()java运行// 核心合理设置核心线程、最大线程、队列长度 ThreadPoolExecutor( corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit, workQueue, threadFactory, rejectHandler )CPU 密集核心线程 ≈ CPU 核心数IO 密集DB / 网络核心线程可以设置为核心数*2~5拒绝策略不要直接 Abort可以自定义队列积压告警不要使用Executors.newFixedThreadPool()无界队列风险并发集合ConcurrentHashMapJDK8 分段锁升级为 CASsynchronized高并发读写首选读多写少CopyOnWriteArrayList注意增删代价极高不适合大量写CompletableFuture 异步编排 合理拆分任务并行执行缩短整体耗时注意异步线程池隔离不要共用同一个线程池避免互相阻塞。四、数据库 IO 性能Java 服务最大瓶颈点绝大多数 Java 接口慢不是代码问题是 DB。JDBC / MyBatis禁止select *只查需要字段合理建立索引避免索引失效like % xxx、隐式转换、or、not in批量操作使用 batch不要循环单次 insert/update分页大数据避免 offset 过大采用主键游标分页连接池HikariCP 最优连接数不是越大越好数据库连接有限过多连接造成数据库上下文切换监控连接泄露长时间不释放连接导致池耗尽缓存热点数据加入本地缓存Caffeine Guava Cache Redis 分布式缓存避免缓存穿透、击穿、雪崩RPC/HTTP 调用使用连接池OkHttp、Apache HttpClient 池化频繁创建销毁连接开销巨大接口超时设置防止阻塞线程池批量接口代替多次循环调用远程服务五、框架层面优化Spring/SpringBootSpringBoot按需自动装配关闭不需要的 AutoConfiguration热加载仅开发使用生产禁用 DevToolsSpring MVC / WebFlux同步阻塞SpringMVCTomcat 线程模型高吞吐 IO 密集场景WebFlux 响应式少量线程支撑大量连接WebFlux 不是天然更快大量等待 IO 场景优势明显CPU 密集无优势对象序列化JSON 序列化Jackson 默认可优化序列化配置高频场景考虑 Hessian、Protostuff、Protobuf避免循环引用导致序列化卡死六、性能排查工具链实操必备线上定位JDK 自带jps查看 Java 进程jstack线程堆栈定位死锁、线程阻塞jmap堆 dumpjmap -dump:formatb,fileheap.hprof pidjhat离线分析堆 dumpjstat实时观测 GC 情况jstat -gc pid 1000可视化工具Arthas阿里线上首选无需停机bash运行# 常用命令 trace 类名 方法名 # 方法内部耗时追踪 watch # 监控入参出参异常 thread # 查看繁忙线程 heapdumpMAT分析 hprof 堆文件定位内存泄漏、大对象JProfiler / YourKit专业性能剖析链路追踪 SkyWalking / Pinpoint定位接口耗时分布区分代码、DB、Redis、RPC 耗时七、经典性能陷阱避坑清单大量使用反射反射开销大高频调用建议使用MethodHandle、或者编译期生成代码MapStruct 替代反射 BeanUtils❌ 禁止循环内频繁BeanUtils.copyProperties正则复杂正则容易回溯造成 CPU 飙升大对象超大数组、超长字符串直接进入老年代诱发 Full GCThreadLocal使用完毕必须 remove否则线程复用造成内存泄漏频繁 System.currentTimeMillis ()高并发可考虑缓存时钟谨慎使用日志生产禁止 debug 日志高并发下避免字符串拼接日志参数使用占位符java运行// 推荐 log.info(user:{}, userId);八、优化实施思路标准流程先定位瓶颈不要盲目优化遵循 80/2080% 耗时集中在 20% 代码先优化 IODB、网络再优化代码最后调 JVM优化前后压测对比JMeter / GatlingQPS、RT、GC 指标量化优先业务算法优化其次语言层面优化算法复杂度 (O (n²)→O (nlogn)) 提升远大于语法微调九、同步阻塞 vs 响应式简单选型建议CPU 密集计算普通同步代码 合理线程池大量并发 IO调用多个 RPC、DB、缓存简单异步CompletableFutureSpringMVC 内异步百万长连接、网关类服务WebFlux Reactor如果你需要我可以进一步输出 1可直接落地的JDK17 ZGC 生产 JVM 参数模板2Arthas 线上排查完整命令手册 3一份 Java 性能优化检查清单可用于代码 CR 4WebFlux / SpringMVC 不同场景性能对比方案你更偏向哪一块深入