解决jvm GC过于频繁的问题

1. 会频繁发生full GC的情况

(1) 频繁的执行System.gc()

(2) 老年代空间增长很快,导致自动触发Full GC,主要是由于新生代的内存空间不足或阈值较小,从而不停的存活对象移到老年代中。

2. 应用实例

JVM配置是这样的: jre1.8, 堆的最大空间是3G,线程执行栈的大小是256K,新生代的大小是1G,老年代的大小是2G.如下图:

结果在日志发现了这个错误:

Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded

这个错误产生的原因是,jvm在进行gc的时候, 使用大于98% 以上的时间去释放小于 2% 的heap空间时,才会报这个异常。

这其实是jvm预判将会发生OutOfMemery异常,就提早抛出这个异常。并不代表jvm没有内存空间了。

于是在tomcat的启动参数里,加入-XX:-UseGCOverheadLimit参数,关闭jvm的预判功能。

再观察,发现没过多久,就发生了java.lang.OutOfMemoryError异常,同时发现年轻代的GC非常频繁(如下图),而且年轻代的内存还有很多剩余空间就发生了GC。怀疑业务代码里执行了System.gc(), 人工触发GC。

可以在tomcat启动参数里加入-XX:+DisableExplicitGC,表示关闭人工GC。意思是,即使在业务代码里有System.gc()的调用,也不会执行GC,相当于执行了一个空调用。

重新启动tomcat再观察:年轻代的GC明显少了,而且每次都是到年轻代的内存空间没有了才GC。这就正常了。

但是这个问题还没有被真真解决,GC正常了,但是还是会发生OutOfMemoryError异常。通过使用jstat -gc pid 3s观察,还会发现:新生代的S1使用空间一直是0,即使发生GC也是0.这说明了两个问题:

1.S1分配了内存,但是一直没有被使用,简直就是浪费。

2.新生代发生GC的时候,Eden和S0的存活对象的总大小,要大于S1的大小。

下图是Heap的分配情况:

为了一次性解决问题,把堆得大小设置为5G,新生代3G,老年代2G。同时,扩大S0和S1的大小。最后的参数是这样的:

-XX:-UseGCOverheadLimit -XX:+DisableExplicitGC -Xms5G -Xmx5G -XX:NewSize=3G -XX:MaxNewSize=3G  -XX:SurvivorRatio=3

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
当Java应用程序在运行过程中遇到JVM闪退问题时,你可以尝试以下一些方法来解决: 1. 检查错误日志:查看JVM生成的错误日志,通常称为堆栈跟踪或崩溃报告。错误日志中可能包含有关引发闪退的异常信息,以及相关的线程信息。通过分析错误日志,你可以获得对问题的更深入理解。 2. 升级JVM:如果你的Java应用程序使用较旧版本的JVM,尝试升级到最新版本。新版本的JVM通常会修复一些已知的问题和漏洞,并提供更好的稳定性和性能。 3. 检查内存使用:JVM闪退可能是由于内存不足或内存泄漏导致的。确保你的应用程序正确地管理和释放内存资源。可以使用Java内存分析工具如VisualVM或MAT来检测内存泄漏并进行调试。 4. 优化代码:一些闪退问题可能与代码逻辑、并发问题或资源管理有关。仔细检查代码,确保没有潜在的问题。使用合适的同步机制和资源释放方式,确保代码的正确性和稳定性。 5. 检查依赖项:某些闪退问题可能与应用程序使用的第三方库或框架有关。确保你的依赖项是最新的,并且与你使用的JVM版本兼容。如果可能,尝试更新或更换依赖项,以解决可能存在的兼容性问题。 6. 调整JVM参数:根据应用程序的需求,适当地调整JVM参数,例如内存大小(-Xmx和-Xms参数)、垃圾回收器类型(-XX:+UseParallelGC或-XX:+UseG1GC等)等。不同的应用程序可能需要不同的JVM参数配置,通过调整这些参数可能有助于解决闪退问题。 7. 与社区寻求帮助:如果上述方法都无法解决问题,你可以向Java开发社区或论坛提问,寻求其他开发者的帮助。他们可能会提供更具体的建议和解决方案。 请注意,JVM闪退问题可能由于多种原因引起,上述方法仅提供了一些常见的解决途径。对于特定的问题,可能需要更详细的调查和分析才能找到准确的解决方案。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值