搞定Java垃圾回收(二)

1、可达性分析算法

可达性分析算法(Reachability Analysis)的基本思路是,通过一些被称为引用链(GC Roots)的对象作为起点,从这些节点开始向下搜索,搜索走过的路径被称为Reference Chain,当一个对象到GC Roots没有任何引用链相连时(即从GC Roots节点到该节点不可达),则证明该对象是不可用的。如下图:

通过可达性算法,成功解决了引用计数所无法解决的问题"循环依赖",只要你无法与GC Root建立直接或间接的连接,系统就会判定为可回收对象,那这样就引申出了另一个问题,哪些输入GC Root

2、Java内存区域

 在Java语言中,可作为GC Root的对象包括以下4种:

  1. 虚拟机栈(栈帧中的本地变量表)中引用的对象
  2. 方法区中类静态属性引用的对象
  3. 方法区中常量引用的对象
  4. 本地方法栈中JNI(即一般说的Native方法)引用的对象

1)  虚拟机栈(栈帧中的本地变量表)中引用的对象
此时的s,即为GC Root,当s置为空时,StackLocalParameter对象也断掉了与GC Root的引用链,将被回收。
public class ReachabilityAnalysisGC {
    public static void main(String[] args){
        testGC();
    }
    public static void testGC(){
        StackLocalParameter s = new StackLocalParameter("StackLocalParameter");
        s = null;
    }
}
class StackLocalParameter {
    public StackLocalParameter(String name){}
}

2)  方法区中类静态属性引用的对象
s为GC Root,s置为null,经过GC后,s所指向的properties对象由于无法与GC Root建立关系被回收
而m作为类的静态属性,也属于GC Root,parameter 对象依然与 GC root 建立着连接,所以此时 parameter 对象并不会被回收。
public class ReachabilityAnalysisGC {
    public static void main(String[] args){
        testGC();
    }
    public static void testGC(){
        MethodAreaStaicProperties s = new MethodAreaStaicProperties("properties");
        s.m = new MethodAreaStaicProperties("parameter");
        s = null;
    }
}
class MethodAreaStaicProperties  {
    public static MethodAreaStaicProperties m;
    public MethodAreaStaicProperties (String name){}
}

3)  方法区中常量引用的对象
m即为方法区中的常量引用的对象,也为GC Root,s置为null后,final对象也不会因没有与GC Root建立联系而被回收
public class ReachabilityAnalysisGC {
    public static void main(String[] args){
        testGC();
    }
    public static void testGC(){
        MethodAreaStaicProperties s = new MethodAreaStaicProperties("staticProperties");
        s = null;
    }
}
class MethodAreaStaicProperties  {
    public static final MethodAreaStaicProperties m =new MethodAreaStaicProperties("final");
    public MethodAreaStaicProperties(String name){}
}

4)  本地方法栈中引用的对象
      任何Native接口都会使用某种本地方法栈,实现的本地方法接口是使用C连接模型的话,那么它的本地方法栈就是C栈。当线程调用Java方法时,虚拟机会创建一个新的栈帧并压入Java栈。然而当它调用的是本地方法时,虚拟机会保持Java栈不变,不再在线程的Java栈中压入新的帧,虚拟机只是简单地动态连接并直接调用指定的本地方法。

 

参考出处:阿里巴巴中间件微信公众号

你的鼓励是我分享技术最大的动力!如有错误之处,请指正,不胜感激。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值