Full GC触发条件总结以及解决策略「建议收藏」

前言FullGC相对于MinorGC来说,停止用户线程的STW(stoptheworld)时间过长,至少慢10倍以上,所以要尽量避免,首先说一下FullGC可能产生的原因,接着给出排查方法以及解决策略。FullGC产生原因下图为与产生FullGC相关的内存区域,初生代、老年代、以及Metaspace区域。System.gc()方法的调用在代码中调用System…

大家好,又见面了,我是你们的朋友全栈君。

前言

Full GC相对于Minor GC来说,停止用户线程的STW(stop the world)时间过长,至少慢10倍以上,所以要尽量避免,首先说一下Full GC可能产生的原因,接着给出排查方法以及解决策略。

Full GC产生原因

下图为与产生Full GC相关的内存区域,初生代、老年代、以及Metaspace区域。

Full GC触发条件总结以及解决策略「建议收藏」

System.gc()方法的调用

在代码中调用System.gc()方法会建议JVM进行Full GC,但是注意这只是建议,JVM执行不执行是另外一回事儿,不过在大多数情况下会增加Full GC的次数,导致系统性能下降,一般建议不要手动进行此方法的调用,可以通过-XX:+ DisableExplicitGC来禁止RMI调用System.gc。

老年代(Tenured Gen)空间不足

在Survivor区域的对象满足晋升到老年代的条件时,晋升进入老年代的对象大小大于老年代的可用内存,这个时候会触发Full GC。

Metaspace区内存达到阈值

从JDK8开始,永久代(PermGen)的概念被废弃掉了,取而代之的是一个称为Metaspace的存储空间。Metaspace使用的是本地内存,而不是堆内存,也就是说在默认情况下Metaspace的大小只与本地内存大小有关。-XX:MetaspaceSize=21810376B(约为20.8MB)超过这个值就会引发Full GC,这个值不是固定的,是会随着JVM的运行进行动态调整的,与此相关的参数还有多个,详细情况请参考这篇文章jdk8 Metaspace 调优

统计得到的Minor GC晋升到旧生代的平均大小大于老年代的剩余空间

Survivor区域对象晋升到老年代有两种情况:

  1. 一种是给每个对象定义一个对象计数器,如果对象在Eden区域出生,并且经过了第一次GC,那么就将他的年龄设置为1,在Survivor区域的对象每熬过一次GC,年龄计数器加一,等到到达默认值15时,就会被移动到老年代中,默认值可以通过-XX:MaxTenuringThreshold来设置。
  2. 另外一种情况是如果JVM发现Survivor区域中的相同年龄的对象占到所有对象的一半以上时,就会将大于这个年龄的对象移动到老年代,在这批对象在统计后发现可以晋升到老年代,但是发现老年代没有足够的空间来放置这些对象,这就会引起Full GC。

堆中产生大对象超过阈值

这个参数可以通过-XX:PretenureSizeThreshold进行设定,大对象或者长期存活的对象进入老年代,典型的大对象就是很长的字符串或者数组,它们在被创建后会直接进入老年代,虽然可能新生代中的Eden区域可以放置这个对象,在要放置的时候JVM如果发现老年代的空间不足时,会触发GC。

老年代连续空间不足

JVM如果判断老年代没有做足够的连续空间来放置大对象,那么就会引起Full GC,例如老年代可用空间大小为200K,但不是连续的,连续内存只要100K,而晋升到老年代的对象大小为120K,由于120>100的连续空间,所以就会触发Full GC。

CMS GC时出现promotion failed和concurrent mode failure

这个原因引发的Full GC可以参考这篇文章,下面也摘抄自这篇文章:JVM 调优 —— GC 长时间停顿问题及解决方法

  1. 提升失败(promotion failed),在 Minor GC 过程中,Survivor Unused 可能不足以容纳 Eden 和另一个 Survivor 中的存活对象, 那么多余的将被移到老年代, 称为过早提升(Premature Promotion)。 这会导致老年代中短期存活对象的增长, 可能会引发严重的性能问题。  再进一步, 如果老年代满了, Minor GC 后会进行 Full GC, 这将导致遍历整个堆, 称为提升失败(Promotion Failure)。
  2. 在 CMS 启动过程中,新生代提升速度过快,老年代收集速度赶不上新生代提升速度。在 CMS 启动过程中,老年代碎片化严重,无法容纳新生代提升上来的大对象,这是因为CMS采用标记清理,会产生连续空间不足的情况,这也是CMS的缺点

总结

可以发现其实堆内存的Full GC一般都是两个原因引起的,要么是老年代内存过小,要么是老年代连续内存过小。无非是这两点,而元数据区Metaspace引发的Full GC可能是阈值引起的,详细原因还是建议参考其他文章,我就不误人子弟了。

检测JVM堆的情况

  1. 可以使用JDK的bin目录下的jvisualvm.exe工具来进行实时监测,这个是图形化界面,最为直观,这是一个强大的工具。
  2. 采用jps找到进行id,然后使用jstat -gc pid来实时进行检测。
  3. 运行程序前设置-XX:+PrintGCDetails,-XX:+PrintGCDateStamps参数打印GC的详细信息进行分析。

Full GC触发条件总结以及解决策略「建议收藏」

Full GC触发条件总结以及解决策略「建议收藏」

Full GC触发条件总结以及解决策略「建议收藏」

 

解决策略

如果是发现由于老年代内存过小频繁引起的Full GC,那么可以适当增加老年代的内存大小,如果是发现是由于老年代没有连续空间来让初生代的对象晋升,如果是采用CMS,那么可以设置进行 n 次 CMS 后进行一次压缩式 Full GC,参数如下:

-XX:+UseCMSCompactAtFullCollection:允许在 Full GC 时,启用压缩式 GC

-XX:CMSFullGCBeforeCompaction=n     在进行 n 次,CMS 后,进行一次压缩的 Full GC,用以减少 CMS 产生的碎片。

除此之外,尽量少创建大对象,不要在代码里调用System.gc(),什么时候进行Full GC这种事情还是交给JVM来做。在读取文件后记得释放资源,不要让JVM无法回收垃圾,造成内存泄漏。

 

本文如果有哪些地方不对,或者有可以补充的地方希望您可以指出来,谢谢了。

 

 

 

参考文献:

https://blog.csdn.net/chenleixing/article/details/46706039

https://blog.csdn.net/YHYR_YCY/article/details/52566105

https://blog.csdn.net/bolg_hero/article/details/78189621

http://www.importnew.com/22886.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/128572.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • UNIX命令

    UNIX命令 一、UNIX命令格式1、UNIX命令提示符   在命令行下,操作系统会显示一提示符,提示用户在此提示符后可以输入一行命令。不同的Shell有不同的缺省提示符:       BShell和KShell的缺省提示符为”$”;       CShell的缺省提示符为”%”;       但当以root用户登录时,系统提示符统一缺省为”#”。用户可以更改自己的缺省Shell和提

    2022年6月1日
    27
  • mysql 更改密码 alter_MySQL修改账号密码方法大全「建议收藏」

    mysql 更改密码 alter_MySQL修改账号密码方法大全「建议收藏」前言:在日常使用数据库的过程中,难免会遇到需要修改账号密码的情景,比如密码太简单需要修改、密码过期需要修改、忘记密码需要修改等。本篇文章将会介绍需要修改密码的场景及修改密码的几种方式。1.忘记root密码忘记root密码的场景还是比较常见的,特别是自己搭的测试环境经过好久没用过时,很容易记不得当时设置的密码。这个时候一般常用的方法是跳过权限验证,然后更改root密码,之后再启用权限验证…

    2022年8月12日
    41
  • 应用程序发生异常0xc0000095_0xc0000142

    应用程序发生异常0xc0000095_0xc0000142Hi,Imadeanexewhichisforsystemtray,thisexetogetsystemeventnotificationas(logoff&Shutdown)..itsworkingfinefor1-2hoursbutafterthatthisexeisgoingtocrashIamunable…

    2022年9月28日
    5
  • 小程序白屏问题和内存研究

    小程序白屏问题和内存研究

    2021年6月18日
    109
  • 6种不同画法画平行线_「精品」漫画人物轮廓画法(精华版)「建议收藏」

    「教程」漫画人物脸部绘画基础part01脸部轮廓的画法(精修版)一、漫画线条与变形想要将人的脸或表情用自己的风格表现出来,需要抓住其特征,然后进行简单化、夸张化的变形,这是不可或缺的手段。在实际开始动笔画之前,关于如何变形要好好考虑清楚。01.简化主线用少量的线条画出角色的特征难度很高。刚开始练习的可以参考照片,拿真人的脸做练习,然后再逐步减少主线的线条,将画面简单化。①细碎的发丝归拢为…

    2022年4月5日
    239
  • Rsync详解_反向ssh

    Rsync详解_反向sshRsync介绍一、什么是rsyncrsync是一款开源,快速,多功能的可实现增量的本地或远程的数据镜像同步备份的优秀工具。适用于多个平台。从软件名称可以看出来是远程同步的意思(remotesync)。可使本地主机不同分区或目录之间及本地和远程两台主机之间的数据快速同步镜像,远程备份等功能。  在同步备份时,默认情况下,rsync通过其独特的“quickcheck”算法,仅同步大小…

    2022年10月13日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号