JVM垃圾回收概念补充

本文深入探讨了JVM的垃圾回收机制,包括System.gc()的理解、手动GC触发不可达对象的回收、内存溢出与内存泄漏的区别、Stop The World现象以及垃圾回收的并行与并发概念。文章通过实例展示了不同情况下对象的回收过程,强调了避免手动调用System.gc()的重要性,同时解释了安全点和安全区域在并发GC中的作用,以及四种引用类型(强引用、软引用、弱引用、虚引用)的特点和应用场景。
摘要由CSDN通过智能技术生成

System.gc()的理解

在默认情况下,通过system.gc()者Runtime.getRuntime().gc() 的调用,会显式触发FullGC,同时对老年代和新生代进行回收,尝试释放被丢弃对象占用的内存。

然而system.gc() )调用附带一个免责声明,无法保证对垃圾收集器的调用。(不能确保立即生效)

JVM实现者可以通过system.gc() 调用来决定JVM的GC行为。而一般情况下,垃圾回收应该是自动进行的,无须手动触发,否则就太过于麻烦了。在一些特殊情况下,如我们正在编写一个性能基准,我们可以在运行之间调用System.gc()

代码演示是否出发GC操作

public class SystemGCTest {
   
    public static void main(String[] args) {
   
        new SystemGCTest();
        // 提醒JVM进行垃圾回收
        System.gc();
        //System.runFinalization();
    }

    @Override
    protected void finalize() throws Throwable {
   
        super.finalize();
        System.out.println("SystemGCTest 执行了 finalize方法");
    }
}

运行结果,但是不一定会触发销毁的方法,因为调用finalize()方法的Finalize线程级别比较低,调用System.runFinalization()会强制调用 失去引用对象的finalize()

SystemGCTest 执行了 finalize方法

手动GC来理解不可达对象的回收

代码如下所示:

public class LocalVarGC {
   

    /**
     * 触发Minor GC没有回收对象,然后在触发Full GC将该对象存入old区
     */
    public void localvarGC1() {
   
        byte[] buffer = new byte[10*1024*1024];
        System.gc();
    }

    /**
     * 触发YoungGC的时候,已经被回收了
     */
    public void localvarGC2() {
   
        byte[] buffer = new byte[10*1024*1024];
        buffer = null;
        System.gc();
    }

    /**
     * 不会被回收,因为它还存放在局部变量表索引为1的槽中
     */
    public void localvarGC3() {
   
        {
   
            byte[] buffer = new byte[10*1024*1024];
        }
        System.gc();
    }

    /**
     * 会被回收,因为它还存放在局部变量表索引为1的槽中,但是后面定义的value把这个槽给替换了
     */
    public void localvarGC4() {
   
        {
   
            byte[] buffer = new byte[10*1024*1024];
        }
        int value = 10;
        System.gc();
    }

    /**
     * localvarGC5中的数组已经被回收
     */
    public void localvarGC5() {
   
        localvarGC1();
        System.gc();
    }

    public static void main(String[] args) {
   
        LocalVarGC localVarGC = new LocalVarGC();
        localVarGC.localvarGC3();
    }
}

依次执行每个方法。

  • 执行localVarGC1()时,输出的GC log如下:
[GC (System.gc()) [PSYoungGen: 12761K->10636K(76288K)] 12761K->10644K(251392K), 0.0077479 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
[Full GC (System.gc()) [PSYoungGen: 10636K->0K(76288K)] [ParOldGen: 8K->10478K(175104K)] 10644K->10478K(251392K), [
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值