• 【JVM】触发 Full GC 的条件


    Java虚拟机(JVM)中,垃圾收集(Garbage Collection,简称GC)是管理内存的关键机制。Full GC(也称为Major GC或老年代GC)是一种较为耗时的垃圾收集过程,会对整个堆(包括年轻代和老年代)进行垃圾收集。

    注:
    部分收集(Partial GC):指目标不是完整收集整个 Java 堆的垃圾收集,其中又分为:
    - 新生代收集(Minor GC/Young GC):指目标只是新生代的垃圾收集。
    - 老年代收集(Major GC/0ld GC):指目标只是老年代的垃圾收集。目前只有CMS 收集器会有单独收集老年代的行为。
    - 混合收集(Mixed GC):指目标是收集整个新生代以及部分老年代的垃圾收集。目前只有 G1收集器会有这种行为。

    整堆收集(Full GC):收集整个 Java 堆和方法区的垃圾收集。

    触发Full GC的条件如下:

    1. Old Generation满

    当老年代(Old Generation)的内存使用达到阈值时,JVM会触发Full GC以释放老年代中的不再使用的对象。

    2. Permanent Generation满

    对于使用旧的HotSpot JVM的Java应用程序,永久代(Permanent Generation)中的内存使用接近或达到上限时,会触发Full GC以回收永久代中的类元数据和静态变量。需要注意的是,JDK 8后永久代被移除了,取而代之的是元空间(Metaspace)。

    3. System.gc()调用

    显式调用System.gc()请求进行垃圾收集时,JVM可能会触发Full GC。尽管JVM并不保证每次都进行Full GC,但在某些情况下会触发。

    4. Heap Dump

    在某些情况下,例如生成堆转储(Heap Dump)以进行内存分析时,JVM会触发Full GC以确保获取准确的堆内存快照。

    5. CMS GC的Promotion Failure

    在使用Concurrent Mark-Sweep(CMS)垃圾收集器时,如果年轻代的对象在转移到老年代时,老年代没有足够的空间来容纳这些对象,会发生Promotion Failure,这会触发Full GC。

    6. G1 GC的Mixed GC失败

    对于G1垃圾收集器(G1 GC),如果在Mixed GC过程中,无法成功回收足够的空间,也可能会触发Full GC。

    7. 内存分配失败

    当JVM尝试分配对象时,如果堆内存中没有足够的空间来容纳新的对象,可能会触发Full GC以回收内存并尝试重新分配。

    8. Metaspace满(对于JDK 8及以后)

    在JDK 8及以后版本,Metaspace替代了永久代。如果Metaspace满,也会触发Full GC以尝试回收类元数据和静态变量。

    示例代码

    以下是一些可能触发Full GC的Java代码示例:

    public class FullGCExample {
        public static void main(String[] args) {
            // 示例1: 手动调用System.gc()
            System.gc();
            
            // 示例2: 分配大量对象导致内存分配失败
            List<byte[]> list = new ArrayList<>();
            try {
                for (int i = 0; i < 1000; i++) {
                    list.add(new byte[1024 * 1024]); // 分配1MB对象
                }
            } catch (OutOfMemoryError e) {
                e.printStackTrace();
            }
    
            // 示例3: 生成Heap Dump
            try {
                // 通过JVM选项触发Heap Dump,例如:-XX:+HeapDumpOnOutOfMemoryError
                // 或通过JVM工具,如jmap -dump:live,format=b,file=heapdump.hprof 
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    总结

    触发Full GC的条件主要包括老年代内存满、显式调用System.gc()、生成Heap Dump、CMS GC的Promotion Failure、G1 GC的Mixed GC失败、内存分配失败和Metaspace满等情况。了解这些条件有助于优化JVM性能,避免频繁触发Full GC对应用性能造成的影响。

  • 相关阅读:
    C&Python:表达式的求值顺序(evaluation order)
    Mybatis - 开启二级缓存和NotSerializableException异常处理
    android 记录Activity和Fragment生命周期顺序
    CV计算机视觉每日开源代码Paper with code速览-2023.11.16
    Qt5开发从入门到精通——第四篇七节(工具盒类)
    c#导入二级树代码备份
    linux下使用vscode对C++项目进行编译
    从零开始,开发一个 Web Office 套件(4):新的问题—— z-index
    LeetCode 第 367 场周赛
    【学习笔记71】数据代理、回调函数和回调地域
  • 原文地址:https://blog.csdn.net/hui_zai_/article/details/139639030