You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 17+ZGC程序长期暂停恢复后出现OutOfMemoryException求助

问题描述

我的应用线程结构如下:

Main Thread -> ScheduleAtFixedRate1 -> ScheduleAtFixedRate3
                                    -> ScheduleAtFixedRate4
            -> ScheduleAtFixedRate2 
  • 主线程(含main方法)启动ScheduleAtFixedRate1和ScheduleAtFixedRate2两个定时任务;ScheduleAtFixedRate1又启动ScheduleAtFixedRate3和ScheduleAtFixedRate4两个定时任务。
  • ScheduleAtFixedRate2定时向服务器请求数据,返回结果包含控制程序暂停的pause变量:当pause=true时,ScheduleAtFixedRate1调用close(true)关闭ScheduleAtFixedRate3和ScheduleAtFixedRate4,此后仅检查pause状态,不再执行完整代码块。
  • 程序以JVM参数-XX:+UseZGC启动,基于Java 17运行,日常运行状态正常,内存分配2GB,平均占用约800MB。
  • 异常现象:程序被长时间暂停(数小时)后恢复,ScheduleAtFixedRate1重启ScheduleAtFixedRate3和ScheduleAtFixedRate4,短暂运行后因thread-x抛出OutOfMemoryException崩溃;短暂暂停(数分钟)无此问题,暂停时间越长崩溃概率越高,偶发崩溃。
  • 推测:ZGC在长期暂停后未正常工作,但不知如何解决,无法共享项目代码。
排查与解决方向

1. 确认定时任务关闭的彻底性

  • 检查close(true)是否真正终止了ScheduleAtFixedRate3和ScheduleAtFixedRate4的线程,是否存在线程未被正确中断、任务队列残留大量未执行任务的情况。长期暂停期间,若任务队列持续堆积,恢复后短时间内大量任务执行可能瞬间占用过高内存。
  • 验证ScheduleAtFixedRate1在pause=true时是否完全停止了新任务的提交,避免恢复前已有大量待执行任务积压。

2. 监控ZGC在暂停前后的状态

  • 启用ZGC的日志记录,添加JVM参数:-Xlog:gc*=info:file=zgc.log:time,uptime,重点查看长期暂停恢复后的GC行为,确认是否存在GC停顿过长、内存回收不及时、对象晋升异常的情况。
  • 检查恢复后内存占用的变化曲线,确认是否是短时间内内存暴涨超出2GB限制,而非ZGC本身失效。

3. 排查内存泄漏点

  • 暂停期间,ScheduleAtFixedRate2仍在运行(假设未被暂停),是否存在持续创建对象但未被回收的情况?比如请求结果的缓存未清理、全局集合持续累积数据。
  • 恢复时重启ScheduleAtFixedRate3和ScheduleAtFixedRate4,是否存在重复创建资源(如连接池、缓存实例)导致的内存叠加?

4. 调整ZGC相关参数

  • 尝试添加-XX:ZCollectionInterval=60(设置GC触发间隔为60秒),强制ZGC定期回收,避免暂停期间内存堆积过多。
  • 调整-XX:ZHeapMaxSize=2g明确最大堆内存,同时检查是否存在堆外内存占用过高的情况(可添加-XX:NativeMemoryTracking=summary监控堆外内存)。

5. 验证线程恢复逻辑

  • 检查ScheduleAtFixedRate1重启任务时,是否对之前的任务实例做了完全清理?是否存在旧实例未被GC回收,与新实例同时占用内存的情况?

内容的提问来源于stack exchange,提问作者KunLun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 16:32:19