Java版本选择直接影响GC行为和吞吐量,JDK 8默认Parallel GC,JDK 11+默认G1或ZGC,JDK 17支持Shenandoah;需匹配构建与运行环境、合理配置JVM参数、避免类路径污染、关注系统级限制。

Java版本选择直接影响GC行为和吞吐量
不同JDK版本的默认垃圾回收器、JIT编译策略、内存模型差异显著。JDK 8 默认使用 Parallel GC,适合吞吐量优先场景;JDK 11+ 默认切换为 ZGC(需显式启用)或 G1 GC,对延迟更友好但配置不当反而增加停顿。
- JDK 17 的
Shenandoah GC在低延迟场景下表现稳定,但要求堆内存 ≥ 4GB 才能发挥优势 - 使用
java -XX:+PrintGCDetails -version可快速确认当前JDK默认GC策略 - 避免混用 JDK 构建与运行环境(如用 JDK 21 编译、JDK 8 运行),会触发
UnsupportedClassVersionError
JVM启动参数不匹配硬件会导致性能断崖
常见错误是直接复制网上“高性能JVM参数”,却忽略CPU核心数、可用内存、容器限制等实际约束。例如在4核2GB的Docker容器中设置 -Xmx4g,会导致OOMKilled而非JVM OOM。
-
-Xms和-Xmx建议设为相同值,避免运行时堆扩容带来的STW暂停 - 容器环境下必须加
-XX:+UseContainerSupport(JDK 10+ 默认开启),否则JVM读取的是宿主机内存而非cgroup限制 -
-XX:MaxRAMPercentage=75.0比硬编码-Xmx更安全,尤其在K8s中
类路径污染和重复依赖引发类加载冲突
运行时出现 NoClassDefFoundError 或 LinkageError,往往不是代码问题,而是 CLASSPATH 中混入了不同版本的同一jar(如两个 slf4j-api-1.7.36.jar 和 slf4j-api-2.0.9.jar)。
- 用
java -verbose:class -jar app.jar 2>&1 | grep 'YourClassName'查看具体由哪个jar加载 - Maven项目建议用
mvn dependency:tree -Dverbose检查传递依赖冲突 - Spring Boot应用优先使用
spring-boot-maven-plugin打包,它会自动排除重复依赖
系统级配置被忽略:文件描述符与线程栈
高并发Java服务常卡在 IOException: Too many open files 或 OutOfMemoryError: unable to create new native thread,根源不在JVM内,而在OS限制。
立即学习“Java免费学习笔记(深入)”;
- Linux下检查当前限制:
ulimit -n(文件描述符)、ulimit -u(用户进程数) - 每个Java线程默认占用约1MB栈空间(
-Xss),500个线程就占0.5GB——若未调小-Xss,极易耗尽内存 - Docker容器需显式设置
--ulimit nofile=65536:65536,否则继承宿主机默认的1024
vm.max_map_count 设置,漏掉任意一层,都可能让优化努力归零。











