JVM full gc 触发原因总结

目录

1. 背景介绍

2. 什么是full gc

3. 垃圾回收算法

4. cms (full gc)触发原因

 

1. 背景介绍

C或者C++的内存申请和销毁需要程序员自己控制,很容易内存泄漏和内存溢出且出现问题查找困难。Java在内存管理的优势在于jvm自己申请和销毁内存,不需要程序员关注内存问题,更专注于业务逻辑。那为什么我们还需要理解JVM的内存管理机制和原理呢?第一、作为有追求的程序猿应该追根刨底,做到知自知彼;第二、当内存管理成为系统性能瓶颈时或者出现内存泄漏、内存溢出问题,程序猿只有了解JVM的内存原理才能够去优化和查找内存问题。第三,我们可能会遇到因为jvm内存回收,正常业务出现卡顿。

由于jvm内容非常之多,这一小节只分析full gc场景产生的原因和如何解决

2. 什么是full gc

这个要从jvm如何管理内存说起,当代主流虚拟机(Hotspot VM)的垃圾回收都采用“分代回收”的算法。“分代回收”是基于这样一个事实:对象的生命周期不同,所以针对不同生命周期的对象可以采取不同的回收方式,以便提高回收效率。

① 新生代(Young Generation):大多数对象在新生代中被创建,其中很多对象的生命周期很短。每次新生代的垃圾回收(又称Minor GC)后只有少量对象存活,所以选用复制算法,只需要少量的复制成本就可以完成回收。

新生代内又分三个区:一个Eden区,两个Survivor区(一般而言),大部分对象在Eden区中生成。当Eden区满时,还存活的对象将被复制到两个Survivor区(中的一个)。当这个Survivor区满时,此区的存活且不满足“晋升”条件的对象将被复制到另外一个Survivor区。对象每经历一次Minor GC,年龄加1,达到“晋升年龄阈值”后,被放到老年代,这个过程也称为“晋升”。显然,“晋升年龄阈值”的大小直接影响着对象在新生代中的停留时间,在Serial和ParNew GC两种回收器中,“晋升年龄阈值”通过参数MaxTenuringThreshold设定,默认值为15。

② 老年代(Old Generation):在新生代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代,该区域中对象存活率高。老年代的垃圾回收(又称Major GC)通常使用“标记-清理”或“标记-整理”算法。整堆包括新生代和老年代的垃圾回收称为Full GC(HotSpot VM里,除了CMS之外,其它能收集老年代的GC都会同时收集整个GC堆,包括新生代)。

③ 永久代(Perm Generation):主要存放元数据,例如Class、Method的元信息,与垃圾回收要回收的Java对象关系不大。相对于新生代和年老代来说,该区域的划分对垃圾回收影响比较小。

各分区的大小对GC的性能影响很大。如何将各分区调整到合适的大小,这个很有讲究,涉及到jvm调优层面的内容,就不细讲了。(一般是参考活跃数据来设置各个区的大小)

讲了这么多,终于入题了,那么什么是full gc 呢,网上其实有很多解读,我们本文暂时以老年代的垃圾回收称之为full gc。(严格来说不算)

 

3. 垃圾回收算法

老年代垃圾回收算法,互联网企业一般都采取cms(Concurrent Mark Sweep) 因为其高并发、高响应的特点,CMS是基于标记-清除算法实现的。具体有哪些算法,这里不细讲,cms也是有缺点的:

a.CMS收集器对CPU资源非常敏感,在并发阶段虽然不会导致用户停顿,但是会占用CPU资源而导致应用程序变慢,总吞吐量下降。

b.CMS收集器无法处理浮动垃圾,可能出现“Concurrnet Mode Failure”,失败而导致另一次的Full GC。

c.CMS收集器是基于标记-清除算法的实现,因此也会产生碎片。

由于cms有这些缺点,而其他算法更不争气,于是出现了G1。相比CMS收集器有不少改进,首先,基于标记-压缩算法,不会产生内存碎片,其次可以比较精确的控制停顿。jdk1.9默认G1

垃圾算法选择依据:

曾经有讲过在heap size<=3G的情况下完全不要考虑CMS GC,在heap size>3G的情况下也优先选择ParallelOldGC,而不是CMS GC,只有在暂停时间无法接受的情况下才考虑CMS GC(不过当然,一般来说在heap size>8G后基本上都得选择CMS GC

4. cms (full gc)触发原因

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 您可以通过以下步骤查看 JVM Full GC 的具体原因: 1. 首先,您需要在 JVM 启动时添加以下参数:-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:<log_file_path> 2. 然后,您需要分析生成的 GC 日志文件,查找 Full GC 的记录。 3. 在 Full GC 记录中,您可以查看以下信息: - Full GC 发生的原因,例如内存不足、永久代满、CMS GC 失败等。 - Full GC 前后堆内存的使用情况,以及 GC 前后各代内存的使用情况。 - Full GC 所花费的时间,以及 Full GC 后堆内存的使用情况。 通过分析这些信息,您可以确定 Full GC 的具体原因,并采取相应的措施来优化应用程序的性能。 ### 回答2: 查看JVM Full GC的具体原因可以通过以下步骤进行: 1. 监控工具:使用一些常见的JVM性能监控工具,如JConsole、VisualVM、Java Mission Control等。这些工具可以提供实时的JVM运行信息,其中包含Full GC的相关指标和堆内存的使用情况。 2. 日志分析:查看应用程序的日志文件,搜索其中包含GC的相关日志。根据GC日志中的时间戳、GC类型和相关指标(如堆内存的使用情况、对象生命周期等),可以进一步分析Full GC原因。 3. 分析GC日志:当JVMGC日志被启用时,可以通过分析GC日志来了解Full GC的具体原因GC日志中会记录GC活动的详细信息,包括GC类型、GC时间、GC前后堆内存的使用情况等。 4. 堆内存分析工具:使用一些堆内存分析工具,如Eclipse Memory Analyzer Tool(MAT),通过导入堆转储快照文件,可以分析堆内存中的对象分布、对象引用关系等,从而找出可能导致Full GC原因。例如,一些内存泄漏或者大对象的创建可能导致堆内存不足,进而引发Full GC的发生。 5. JVM参数调整:根据分析结果,如果是堆内存不足导致Full GC的话,可以考虑调整JVM的相关参数,如-Xmx(最大堆大小)、-Xms(初始堆大小)等,增加堆内存的分配。 综上所述,通过使用监控工具、分析GC日志、堆内存分析工具以及调整JVM参数等方法,可以查看JVM Full GC的具体原因。 ### 回答3: 要查看JVM Full GC的具体原因,可以按照以下步骤进行: 1. 设置JVM日志级别:在启动JVM时,使用-XX:+PrintGCDetails或-XX:+PrintGCTimeStamps等参数,将JVMGC日志级别设置为详细模式。这样可以确保在日志中记录Full GC事件的详细信息。 2. 分析GC日志:定期检查和分析JVMGC日志。在GC日志中,Full GC事件通常以“Full GC”或“Full GC(System)”的形式出现。同时会显示一些关键信息,如Full GC消耗的时间、GC前后堆内存的情况等。 3. 查看GC原因:在GC日志中,找到Full GC事件的触发原因。可能的原因包括年轻代或老年代空间不足、永久代空间不足、老年代对象引用链过长等。根据Full GC事件的触发原因,可以进一步分析和解决问题。 4. 使用工具进行分析:可以使用一些专门的工具来分析GC日志,如GCViewer、GCMV等。这些工具可以图形化地展示GC事件的情况,包括GC发生的次数、GC消耗的时间、堆内存的变化等。通过这些工具,可以更直观地查看和分析Full GC的具体原因。 5. 进行性能调优:根据Full GC的具体原因,进行相应的性能调优操作。例如,如果是堆内存不足导致的Full GC,可以通过增加堆内存大小来解决问题;如果是对象引用链过长导致的Full GC,可以优化代码,减少对象间的引用链长度等。 通过以上方法,可以查看JVM Full GC的具体原因,并根据需要进行相应的优化和调整,以提高系统性能和稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值