Java垃圾回收机制-可达性分析算法教你GC如何判断对象的存活

Java垃圾回收机制-可达性分析算法解析

前言

Java回收机制是什么?可达性分析算法,可达性分析算法最重要的就是要先知道哪些对象死了,怎么知道对象已经死了呢,就要找到GCRoot对象,然后顺着引用路径一直找下去,如果GCRoot下面没有对象引用链,那么这些对象就可以认为是濒临死亡状态,等着垃圾回收器回收了。那么哪些对象是GCRoot对象,这个是关键,所以先要搞清楚GC Roots对象包含哪些,下面我来给大家通过GC Roots的对象定义,以及代码示例来简单理解一下java中GC是如何判断对象存活的。

一、可达性分析

在java中,作为GC Roots的对象包括

  1. 方法区:类静态属性的对象
  2. 方法区:常量的对象
  3. 虚拟机栈(本地变量表)中的对象
  4. 本地方法栈JNI(Native)中的对象
public class GCRootsTest {
   /**
     * 可达性分析算法
     */
    Object o =new Object();
    static Object GCRoot1 =new Object(); //GC Roots
    final  static Object GCRoot2 =new Object();//GC Roots
    public void haveGCRootMethod() {
        //可达
        Object object1 = GCRoot1; //=不是赋值,在对象中是引用,传递的是右边对象的地址
        Object object2 = object1;
        Object object3 = object1;
        Object object4 = object3;
    }
    public void notGCRootMethod(){
        //不可达(方法运行完后可回收)
        Object object5 = o;//o不是GCRoots
        Object object6 = object5;
        Object object7 = object5;
    }
    //本地变量表中引用的对象
    public void stack(){
        Object ostack =new Object();    //本地变量表的对象
        Object object8 = ostack;
        //以上object8 在方法没有(运行完)出栈前都是可达的
    }
 }

参考示意图:
GCROOT可达性分析

二、结果分析

haveGCRootMethod方法中:

    static Object GCRoot1 =new Object(); //GC Roots
    final  static Object GCRoot2 =new Object();//GC Roots
这两段代码的属性声明,分别是静态和常量,均在方法区中,所以是GC Roots节点,我们找到了GCRoot节点,随后object1、object2、object3、object4依次引用GCRoot1节点,自然形成图中的一条引用链,所以这几个对象都是活着的,不会被垃圾回收器回收。

notGCRootMethod方法中:
首先,要知道类中声明的代码段o不是GCRoot对象

Object o =new Object();

o这个对象在哪呢,它不在GCRoots区域,它在区域外面,我忘记画了o
当notGCRootMethod方法执行过程中,object5、object6、object7均在GCRoot区域中,但是object5引用了非GCRoots区域的o对象,指向o,随着方法运行结束,那么object5、object6、object7将会移出GCRoots区域,这个时候就是你看见图中所在的位置,接着,等着被垃圾回收器回收。

stack方法中:
是本地变量表中引用的对象,在方法没有执行结束之前,object8都是可达的,并且引用ostack对象,存在GCRoots区域中,但是当方法结束以后,就会像上图那样移出GCRoots区域,等着被垃圾回收器回收

三、如何减少OOM概率

  1. 尽可能少的发生内存泄露
  2. 尽可能不在循环中申请内存
  3. 尽可能不在调用次数多的函数申请内存
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

慕容野野

需要你的肯定

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

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

打赏作者

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

抵扣说明:

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

余额充值