Java虚拟机(三) - GC垃圾回收

一、什么时候需要回收

Java使用可达性分析(Reachability Analysis)来判断对象是否存活。

这个算法的基本思想是:通过一系列称为"GC Roots"的对象作为起始点,从这些结点向下搜索,搜索所走过的路称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,证明这个对象时不可用的。被判断为可回收对象。

可做为GC Roots的对象包括:

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

注意:并不是被判断为可回收对象后,该对象一定会被回收。

对象被判定为可回收后,会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过,虚拟机将这两种情况视为“没有必要执行”。

如果对象被判定“没有必要执行”,这个对象将会放置在一个叫做F-Queue的队列之中,稍后在虚拟机自动建立的、低优先级的Finalizer线程去执行它(在线程里执行对象的finalize方法)。

如果对象在finalize()方法中成功拯救了自己(重新与引用链上的任何对象建立关联),在第二次标记的时候,该对象被移出“即将回收”的集合;反之,对象被回收。

其他可以回收的情况(仅仅是可以回收,但不一定回收)

  1. 废弃常量
    没有任何String对象引用常量池中的"abc"常量,也没有其他地方引用了这个字面量,"abc"为废弃常量
  2. 无用的类(同时满足以下三个条件)
    堆中不存在该类的任何实例;
    加载该类的ClassLoader已经被回收;
    该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法(就是没有地方用到xx.Class);
二、怎么回收

具体回收操作是通过垃圾收集器实现的。
常见的垃圾收集器有G1,CMS等。

回收算法

  • 标记-清除
    顾名思义,标记需要回收的对象,然后清楚。但这样容易造成清理后的内存空间不是连续的。
  • 标记-整理
    同样,先标记,将存活的对象都移动到一边,清理另一边的空间。
  • 复制
    将内存分为两块,每次只用其中一块,当这块用完了,将存活着的对象复制到另一块,当前这块全部清理掉。
  • 分代
    把堆分为新生代和年老代(Java8以前还有持久代),根据年龄特点回收。

这篇文章建议配合我的上篇文章一起阅读 Java虚拟机(二) - 对象 创建流程、内存分配


[1] 周志明 · 深入理解Java虚拟机 :机械工业出版社

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值