简洁明了!对垃圾回收机制了然于心


前言:什么才算JAVA堆中运行中的垃圾

当一个对象不再被任何对象引用时,这个对象就已经失去了被使用的机会,系统会将其判定为垃圾。

1.引用计数算法

在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加一;当引用失效时,计数器值就减一;任何时刻计数器为零的对象就是不可能再被使用的。这样看来其原理简单,判定效率也很高
但其无法解决相互循环利用的问题:

a.instance()=b;
b.instance()=a;

这样子的情况,两个实例都互相引用,引用计数不为0,但你根本访问不了(说明这两个对象已经没用了),垃圾收集也无法收集。

2.可达性分析算法(追踪式收集)

在这里插入图片描述
通过类似树的数据结构来实现,有一个根节点,每次遍历这个树的时候,查看有哪些节点不能到达Root根节点,这些节点就会被垃圾收集。

2.1 GC Root判定

GCRoot算是一个图,虚拟机可以循着图来查询引用关系,只需要和每个引用对象的指针或者标记打交道就行了!
Root不止一个,可以作为根节点的引用可以是
1、线程中的局部变量,形参
2、静态属性引用的类
3、常量引用的类
4、本地方法引用的对象
5、虚拟机内部引用
6、同步锁持有的对象
7、反应java内部情况的回调

3.引用

强引用:只要强引用关系还在,就不会被垃圾收集
软引用:当内存空间不够时,第二次的垃圾收集将会收集软引用关系
弱引用:该引用关系不会生存到下一次垃圾收集了,(只要发生垃圾收集,弱引用直接被清除)
虚引用:不会影响被引用的对象,也不能够获得对象实例,唯一目的是当其被垃圾收集时会发出通知。

4.是否“死亡”的判定

一个对象真正死亡需要两次标记的判定
第一次标记:先查询该对象与GC Root是否有通路,没有则标记一次,然后查看其是否应该执行finalize方法(当该对象没有finalize方法或者该方法已经被虚拟机执行过都将视为没必要执行,没必要执行的,被当作垃圾收集掉,所以每个对象只有一次自救机会),若有必要执行则将其加入F_Queue队列。为了保证队列中每个finalize方法不会进入死循环阻塞队列,虚拟机只确保它执行了finalize方法,不确保其执行完毕。
第二次标记: 执行完finalize方法后,进行第二次标记,还是查与Root有没有通路,所以可以在finalize方法中赶紧找到一个引用自己的方法,与其中一个Root取得连接,拯救自己。

5.方法区回收

主要回收未使用的常量和类
判定类没被使用的三个条件:
1、该类的所有实例全部被回收,包括其派生的子类
2、该类的类加载器被回收,很难实现
3、该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值