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

一 代码

/**
* 手动 GC 来理解不可达对象的回收
* -XX:+PrintGCDetails
*/
public class LocalVarGC {
    // 触发 Minor GC 没有回收对象,然后在触发 Full GC 将该对象存入old区
    public void localvarGC1() {
        byte[] buffer = new byte[10 * 1024 * 1024]; // 10MB
        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 local = new LocalVarGC();
        local.localvarGC1();
        // local.localvarGC2();
        // local.localvarGC3();
        // local.localvarGC4();
        // local.localvarGC5();
    }
}

1 localvarGC1() 测试

[GC (System.gc()) [PSYoungGen: 13930K->840K(71680K)] 13930K->11088K(235520K), 0.0077022 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

[Full GC (System.gc()) [PSYoungGen: 840K->0K(71680K)] [ParOldGen: 10248K->10840K(163840K)] 11088K->10840K(235520K), [Metaspace: 3203K->3203K(1056768K)], 0.0078262 secs] [Times: user=0.03 sys=0.00, real=0.01 secs]

new byte[10 * 1024 * 1024] 没有回收。

说明:触发 Minor GC 没有回收对象,然后在触发 Full GC 将该对象存入 old 区。

2 localvarGC2() 测试

[GC (System.gc()) [PSYoungGen: 13930K->776K(71680K)] 13930K->784K(235520K), 0.0009854 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[Full GC (System.gc()) [PSYoungGen: 776K->0K(71680K)] [ParOldGen: 8K->599K(163840K)] 784K->599K(235520K), [Metaspace: 3187K->3187K(1056768K)], 0.0048599 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]

new byte[10 * 1024 * 1024] 被回收。

说明:触发 YoungGC 的时候,已经被回收了。

3 localvarGC3() 测试

[GC (System.gc()) [PSYoungGen: 13930K->776K(71680K)] 13930K->11024K(235520K), 0.0064986 secs] [Times: user=0.09 sys=0.00, real=0.01 secs]

[Full GC (System.gc()) [PSYoungGen: 776K->0K(71680K)] [ParOldGen: 10248K->10841K(163840K)] 11024K->10841K(235520K), [Metaspace: 3203K->3203K(1056768K)], 0.0078091 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

new byte[10 * 1024 * 1024] 没有回收。

说明:不会被回收,因为它还存放在局部变量表索引为1的槽中。

4 localvarGC4() 测试

[GC (System.gc()) [PSYoungGen: 13930K->712K(71680K)] 13930K->720K(235520K), 0.0025408 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[Full GC (System.gc()) [PSYoungGen: 712K->0K(71680K)] [ParOldGen: 8K->600K(163840K)] 720K->600K(235520K), [Metaspace: 3193K->3193K(1056768K)], 0.0063685 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

new byte[10 * 1024 * 1024] 被回收。

说明:会被回收,因为它还存放在局部变量表索引为1的槽中,但是后面定义的 value 把这个槽给替换了。

5 localvarGC5() 测试

[GC (System.gc()) [PSYoungGen: 13930K->712K(71680K)] 13930K->10960K(235520K), 0.0074081 secs] [Times: user=0.03 sys=0.03, real=0.01 secs]

[Full GC (System.gc()) [PSYoungGen: 712K->0K(71680K)] [ParOldGen: 10248K->10838K(163840K)] 10960K->10838K(235520K), [Metaspace: 3184K->3184K(1056768K)], 0.0081957 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

[GC (System.gc()) [PSYoungGen: 0K->0K(71680K)] 10838K->10838K(235520K), 0.0003689 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[Full GC (System.gc()) [PSYoungGen: 0K->0K(71680K)] [ParOldGen: 10838K->598K(163840K)] 10838K->598K(235520K), [Metaspace: 3184K->3184K(1056768K)], 0.0048605 secs] [Times: user=0.05 sys=0.01, real=0.00 secs]

说明:因为 localvarGC1 结束后,对应的方法栈就没有了,new byte[10 * 1024 * 1024] 就失去了引用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值