System.gc()做了什么?

24 篇文章 0 订阅

1. System.gc()

System.gc()我们都知道是手动垃圾回收,这点无需多说,今天我们来了解一下System.gc()是怎么进行垃圾回收的。
System.gc()内部调用了 Runtime.getRuntiom

public static void gc() {
    Runtime.getRuntime().gc();
}

在往深一层则是本地方法了

public native void gc();

System.gc()会执行FullGC,对新生代和老年代进行回收
注意: 此时垃圾回收线程可能并不会立即执行
证明:

package com.zy.study14;

/**
 * @Author: Zy
 * @Date: 2021/12/29 11:13
 * 测试system.gc()方法
 */
public class SystemGcTest {
    public static void main(String[] args) {
        new SystemGcTest();

        // 告知垃圾回收器执行垃圾回收,当并不一定立刻执行
        // 证明如下: 如果执行了就会执行finalize方法,否则程序结束,垃圾回收线程也不会执行
        System.gc();

        // 立刻执行对象的finalize方法
        //System.runFinalization();

    }

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

以下五种情况测试System.gc对对象的回收,同时验证垃圾回收算法的回收。
System.gc对对象的回收情况:

package com.zy.study14;

/**
 * @Author: Zy
 * @Date: 2021/12/29 11:30
 * 测试垃圾回收对象
 * -XX:+PrintGCDetails 打印gc细节
 */
public class SystemGcObjectTest {

    public void test1(){
        // 栈中有引用不会回收
        byte[] buffer = new byte[10*1024*1024];
        System.gc();
    }

    public void test2(){
        // 将引用置空,此时可以回收
        byte[] buffer = new byte[10*1024*1024];
        buffer = null;
        System.gc();
    }

    public void test3(){
        // 代码块中引用并没有被覆盖,局部变量表中深度为2,第一个变量为this,第二个仍然为buffer,有该引用,所以不会被回收
        {
            byte[] buffer = new byte[10*1024*1024];
        }
        System.gc();
    }

    public void test4(){
        // 代码块中buffer引用被被覆盖,局部变量表中深度为2,第一个变量为this,第二个buffer被覆盖为value,引用置空,所以被回收
        {
            byte[] buffer = new byte[10*1024*1024];
        }
        int value = 10;
        System.gc();
    }

    public void test5(){
        // 引用置空 会被回收
        test1();
        System.gc();
    }

    public static void main(String[] args) {
        SystemGcObjectTest systemGcObjectTest = new SystemGcObjectTest();
        systemGcObjectTest.test1();
    }
}

通过对打印的gc信息可以观察到是否符合该方法中描述的回收情况,同时可以结合jclasslib查看局部变量表引用信息.
方法1,2,5都是比较简单的
比较复杂的就是3和4
针对3来说:
image.png
image.png
局部变量表的深度为2,但是变量表里只显示this对象,索引为1的仍然是代码块中的buffer引用.所以不会回收.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhang.yao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值