局部变量表中Slot复用对垃圾回收的影响详解

看两段代码
1.

package com.jvm;

public class Test {
    public static void main(String[] args) {
        {
            byte[] placeholder = new byte[64 * 1024 * 1024];
            //不加这个b看不到局部变量表中的placeholder,
            // 因为最后一个变量总是会看不到
            int b = 0;
        }
        System.gc();
    }
}

加入运行时参数-verbose:gc看一下内存,明显64000K的数组没被回收
在这里插入图片描述
javac -g Test.java 编译一下
javap -verbose Test.class 查看字节码
看局部变量表LocalVariableTable
在这里插入图片描述
Slot从1开始的,前面0是mian方法的参数args,如果不是main方法那0是调用方法的对象的引用this
这里Slot没有被复用,所以作为GC Roots的一部分的局部变量表仍保持着对它的关联,这种关联没有被及时打断,所以GC回收不了它
2.

package com.jvm;

public class Test {
    public static void main(String[] args) {
        {
            byte[] placeholder = new byte[64 * 1024 * 1024];
            int b = 0;
        }
        int a = 0;
        System.gc();
    }
}

回收成功
在这里插入图片描述在这里插入图片描述
这里的int a复用了placeholder占用的从1开始的空间,所以GC Roots被覆盖掉了,所以成功回收

不过在经过JIT编译器的优化后,是可以正确回收内存的,所以不用太担心这个问题

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值