SpringBoot 3(JDK17)应用无日志异常崩溃重启求助
SpringBoot 3 + JDK17迁移后应用无日志崩溃、OOM-Kill及CPU飙高问题
问题现象
将SpringBoot应用迁移至SpringBoot 3与JDK 17后,出现以下异常:
- 应用无报错日志直接崩溃
- 配置的自动重启脚本导致应用持续重启,加剧系统负载
- 添加JVM参数
-XX:+HeapDumpOnOutOfMemoryError后未生成堆转储文件 - 执行
top命令发现CPU占用飙至300%+ - 在
/var/log/messages中捕获到内核OOM-Kill日志,仅能看到部分应用启动日志
捕获的内核OOM-Kill日志
Oct 23 07:00:34 CMSNFV-P_9_0_14_A kernel: oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0-1,global_oom,task_memcg=/system.slice/psmon.service,task=java,pid=34091,uid=1006 Oct 23 07:00:34 CMSNFV-P_9_0_14_A kernel: Out of memory: Killed process 34091 (java) total-vm:315588020kB, anon-rss:570068kB, file-rss:0kB, shmem-rss:4624624kB, UID:1006 pgtables:13160kB oom_score_adj:0
仅有的应用日志片段
2023-10-20 12:38:38,043 ERROR c.m.c.v.s.i.SubscriberQueryRequestHandler [Scheduler-task-12] subQueryLst.size():0 2023-10-20 12:38:44,104 INFO o.s.b.StartupInfoLogger [main] Starting Application v0.0.1 using Java 17.0.8 with PID 58021 (/opt/dist/WebController/cms-service-0.0.1.war started by cms in /) 2023-10-20 12:38:44,114 DEBUG o.s.b.StartupInfoLogger [main] Running with Spring Boot v3.1.4, Spring v6.0.12 2023-10-20 12:38:44,115 INFO o.s.b.SpringApplication [main] No active profile set, falling back to 1 default profile: "default" 2023-10-20 12:38:49,470 DEBUG c.m.c.v.u.LoggingAspect [main] com.mavenir.cms.JasyptEncryptionConfig$$SpringCGLIB$$0|Entered method : passwordEncryptor 2023-10-20 12:38:49,470 DEBUG c.m.c.v.u.LoggingAspect [main] com.mavenir.cms.JasyptEncryptionConfig$$SpringCGLIB$$0|passwordEncryptor arguments are : []
OOM-Kill日志核心含义
global_oom:整个系统内存耗尽触发内核OOM机制,而非单个进程组(cgroup)内存不足shmem-rss:4624624kB:Java进程占用了约4.4G的共享物理内存,这是导致系统OOM的核心原因- 未生成JVM堆转储的原因:本次OOM是系统级内存耗尽,而非JVM堆内存不足,因此
-XX:+HeapDumpOnOutOfMemoryError不会触发 total-vm:315588020kB:虚拟内存约301G,仅代表进程地址空间大小,不反映实际物理内存占用
解决方案
紧急临时处理
- 停止自动重启脚本,避免持续重启加剧内存消耗:
systemctl stop psmon.service(根据实际服务名调整) - 清理无用共享内存:用
ipcs -m列出所有共享内存段,通过ipcrm -m <shmid>删除未被使用的大内存段(注意不要误删正在使用的段)
根本问题排查与修复
定位共享内存占用来源
- 检查应用是否使用依赖共享内存的组件(如IPC缓存、第三方中间件客户端),排查JDK17迁移后是否存在共享内存未正确释放的兼容问题
- 用
pmap -x <java-pid>查看进程内存映射,定位大共享内存段关联的模块或依赖
调整内存限制配置
- 限制Java进程总内存占用:添加JVM参数
-XX:MaxRAMPercentage=70(根据系统总内存调整,建议预留20%-30%内存给系统),同时指定堆转储路径-XX:HeapDumpPath=/opt/heap-dumps/(确保路径有写入权限) - 通过systemd配置服务内存配额:修改
psmon.service配置文件,添加MemoryMax=8G(根据实际情况调整),避免单个进程耗尽系统内存
- 限制Java进程总内存占用:添加JVM参数
兼容性问题排查
- 检查第三方依赖库版本是否兼容JDK17,尤其是涉及本地内存、共享内存操作的库,替换为官方兼容版本
- 对比SpringBoot 2与3的自动配置差异,排查是否因缓存、线程池等组件行为变化导致内存泄漏或过度占用资源
CPU飙高问题处理
- 应用启动时CPU飙高,大概率是初始化逻辑(如大量数据加载、依赖初始化)存在性能瓶颈,或OOM前频繁GC导致
- 用
jstack <java-pid>获取线程栈,排查是否存在死循环、大量阻塞线程;用jstat -gc <java-pid> 1000实时监控GC情况,判断是否因GC频繁导致CPU占用过高
内容的提问来源于stack exchange,提问作者manjosh
相关产品推荐
相关产品推荐

