GC overhead limt exceed 导致的java进程假死

本文详细记录了一次线上后台Java进程出现假死状态的排查过程,通过分析线程状态和GC情况,最终定位问题为内存设置过小导致的频繁GC,并提出了调整-Xms和-Xmx参数的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.现象

线上后台任务的java进程处于假死状态

2.排查过程

1.查看假死的进程ID
ps -ef | grep sku

2.将该进程的所有线程信息打印输出至指定文件
jstack -F 8843 >> jstack-8843.log
3.查看该日志文件前500行的信息
head -n 500 jstack-8843.log

No deadlocks found,代表没有发现死锁,所有的线程都处于BLOCKED状态

4.查看GC的情况,每隔2s打印一次,一共打印20次
jstat -gc 8843 2000 20

发现gc的次数在疯狂增长,其次在该进程业务日志中发现java.lang.OutOfMemoryError: GC overhead limit exceeded

GC overhead limt exceed检查是Hotspot VM 1.6定义的一个策略,通过统计GC时间来预测是否要OOM了,提前抛出异常,防止OOM发生。Sun 官方对此的定义是:“并行/并发回收器在GC回收时间过长时会抛出OutOfMemroyError。过长的定义是,超过98%的时间用来做GC并且回收了不到2%的堆内存。用来避免内存过小造成应用不能正常工作。“

3.结论

基本可以判断为程序的内存设置过小,导致频繁GC,引起假死,调整 -Xms -Xmx 即可

转载于:https://my.oschina.net/xiongying0214/blog/3000378

`java.lang.OutOfMemoryError: GC overhead limit exceeded` 是Java中常见的内存溢出错误,特别是当垃圾回收(Garbage Collection, GC)机制在试图释放内存时消耗了过多的时间,导致程序无法继续执行。这个错误提示表明系统的大部分时间都花在了垃圾回收上,而不是在正常的程序逻辑上。 具体来说,Java有一个称为“Garbage Collection Overhead Limit”的阈值,当垃圾回收所用的时间超过这个限制(默认为98%),并且连续几次达到这个比例,就会抛出这个异常。这通常是由于以下几个原因: 1. **内存泄漏**:程序中的对象没有被正确地清理,导致内存占用持续增加。 2. **大量短期对象**:创建了大量的小对象,尽管它们很快会被垃圾回收,但大量这样的操作会频繁触发GC。 3. **大对象或数据结构**:大的对象或复杂的对象结构导致一次性分配大量内存,使得GC难以快速回收。 4. **并发问题**:在多线程环境中,如果GC在并发时执行得不够高效,也可能引发此错误。 为了解决这个问题,你可以尝试以下策略: - **优化代码**:检查是否存在内存泄漏,减少不必要的对象创建,尤其是避免创建大量短期对象。 - **调整堆大小**:根据应用的需求和限制,适当增大Java虚拟机(JVM)的堆大小,但过大可能会导致更严重的性能问题。 - **启用分代垃圾回收**:设置新生代和老年代的大小,以及新生代的吞吐量或暂停时间,帮助GC更有效地工作。 - **使用并发GC**:启用并行或并发的垃圾回收器,如G1或ZGC,可以提高效率。 - **使用JVM参数**:例如 `-XX:MaxGCPauseMillis` 可以设置最大停顿时间,限制GC对程序运行的影响。 如果你需要详细了解如何调整JVM参数或解决特定的内存溢出问题,可以告诉我,我会进一步指导你。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值