Java虚拟机垃圾收集器简要描述

提示:参考深入理解Java虚拟机


垃圾回收的区域

程序计数器,虚拟机栈,本地方法区都是随着线程生命周期的,而且在类的结构确定的时候就已经确定了,所以垃圾回收区域不包含这几个区域;Java堆和方法区有很明显的不确定性,堆存储的是对象实例,方法区的运行时常量池也在堆中,因为涉及到接口不同的实现类,需要的内存不同,方法执行时不同的分支需要的内存也不一样,只有运行时才知道会创建哪些对象。所以这部分是动态的,也是垃圾回收的主要区域

一、判断对象是否存活(回收前做的第一件事)

有两种比较出名的算法:

  1. 引用计数法:给对象添加引用计数器,一引用就加一,失效就减一;但是一般主流的虚拟机都不采用这个方法。这个方法虽然很简单,但是有些复杂情况没有考虑,比如对象间循环引用

  2. 可达性算法(主流商用语言的选择):
    通过GC Root的跟对象作为起点集合,从这些节点开始根据引用关系向下搜索,搜索走过的路径叫做引用链,如果一个对象没有和GC Root有任何的引用链相连,就证明这个对象不会被使用了,可以回收掉(在前面OOM实战文章的代码中我们把对象放在list里面,这个list是Java方法运行时的局部变量,这个局部变量就可以作为GCRoot集)
    在这里插入图片描述
    可以作为GCRoot的对象:

  3. 虚拟机栈本地变量引用的对象

  4. 方法区中类静态属性引用的对象

  5. 方法区中常量引用的对象(比如字符串常量池的引用)

  6. 本地方法栈引用的对象

  7. 虚拟机内部引用–基本数据类型对用的class对象,系统类加载器

  8. 所有被同步锁(synchronized)持有的对象

  9. 反映Java虚拟机内部情况的JMXBean等
    (1.2后引用分强(new的),软,弱,虚(在localTHread中应用)

二、缓刑阶段

用可达性算法判断对象不可达,不会马上杀死对象,最少会有两次标记过程
可达性判断不可达标记,然后在标记的对象里面筛选这个对象有没有必要执行finalize()方法—覆盖finalize()或者没有被执行过finalize()方法
如果有必要执行,就会加入一个队列等死
但是如果在第二次标记前重新被引用就可以逃脱死刑
代码:

/**
 * @author jc
 */
public class SaveObject {
    private static SaveObject Save = null;

    public void isAlive() {
        System.out.println("我还活着!!!");
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("执行finalize()");
        Save = this;
    }


    public static void main(String[] args) throws InterruptedException {
        Save = new SaveObject();

        Save = null;

        System.gc();

        Thread.sleep(500);
        if (Save != null) {
            Save.isAlive();
        } else {
            System.out.println("我没了!!!!");
        }


        Save = null;

        System.gc();

        Thread.sleep(500);
        if (Save != null) {
            Save.isAlive();
        } else {
            System.out.println("我没了!!!!");
        }
    }


}

结果
在这里插入图片描述


总结

大概描述了垃圾回收的主流思想:先判断对象该不该死,然后执行死刑

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值