如何判定对象可以回收

1.引用计数法中循环引用的问题

啥是引用计数法
顾名思义,就是当一个对象被引用的时候进行数字计数,当增加一次引用的时候计数+1,当删除一个对象的引用时-1;当一个对象的引用变成0的时候,就可以被回收了

在这里插入图片描述
在这里插入图片描述

2.可达性分析算法

https://www.cnblogs.com/yixiaofeng/p/11985040.html
GcRoot是垃圾回收器算法中判断一个对象是否可以回收的一种算法

就是对象到达GcRoot的路径是否还有可达,即是否有可引用链,如果有,这表明对象还存在着引用,
如果没有,则表明该对象没有引用,在下一次垃圾回收时就会被回收
在这里插入图片描述

GcRoot的种类

  • 虚拟机栈:栈帧中的本地变量表引用的对象
  • native方法引用的对象
  • 方法区中的静态变量和常量引用的对象
    在这里插入图片描述

jmap命令可以获得运行中的jvm的堆的快照,从而可以离线分析堆,以检查内存泄漏,检查一些严重影响性能的大对象的创建,检查系统中什么对象最多,各种对象所占内存的大小等等

F:\workspace\jvmdemo\test>jps
11428
3588 Jps
1260 Demo2_2

F:\workspace\jvmdemo\test>jmap -dump:format=b,live,file=1.bin 1260
Dumping heap to F:\workspace\jvmdemo\test\1.bin ...
Heap dump file created

F:\workspace\jvmdemo\test>jmap -dump:format=b,live,file=2.bin 1260
Dumping heap to F:\workspace\jvmdemo\test\2.bin ...
Heap dump file created

MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。
Eclipse–>File菜单–>Open file–>Open file:打开Getting Started Wizard,选择Leak Suspects Report–>Java Basics–>GC roots
在这里插入图片描述

四种引用

  • 强引用
    只有所有 GC Roots 对象都不通过【强引用】引用该对象,该对象才能被垃圾回收

  • 软引用(SoftReference)
    仅有软引用引用该对象时,在垃圾回收后,内存仍不足时会再次出发垃圾回收。回收软引用
    对象可以配合引用队列来释放软引用自身

  • 弱引用(WeakReference)
    仅有弱引用引用该对象时,在垃圾回收时,无论内存是否充足,都会回收。弱引用对象
    可以配合引用队列来释放弱引用自身

  • 虚引用(PhantomReference)
    必须配合引用队列使用,主要配合 ByteBuffer 使用,被引用对象回收时,会将虚引用入队,
    由 Reference Handler 线程调用虚引用相关方法释放直接内存
    在这里插入图片描述

  • 终结器引用(FinalReference)
    A4对象重写finalize()方法,会自动生成一个终结器引用。在垃圾回收时,内部配合引用队列使用,终结器引用入队(被引用对象A4暂时没有被回收),再由 Finalizer 线程通过终结器引用找到被引用对象并调用它的 finalize方法,第二次 GC 时才能回收被引用对象
    在这里插入图片描述

/**
 * 演示软引用
 * -Xmx20m -XX:+PrintGCDetails -verbose:gc
 */
public class Demo2_3 {

    private static final int _4MB = 4 * 1024 * 1024;



    public static void main(String[] args) throws IOException {
       /* List<byte[]> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            list.add(new byte[_4MB]);
        }

        System.in.read();*/
        soft();


    }

    public static void soft() {
        // list --> SoftReference --> byte[]

        List<SoftReference<byte[]>> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            SoftReference<byte[]> ref = new SoftReference<>(new byte[_4MB]);
            System.out.println(ref.get());
            list.add(ref);
            System.out.println(list.size());

        }
        System.out.println("循环结束:" + list.size());
        for (SoftReference<byte[]> ref : list) {
            System.out.println(ref.get());
        }
    }
}

/**
 * 演示软引用, 配合引用队列
 */
public class Demo2_4 {
    private static final int _4MB = 4 * 1024 * 1024;

    public static void main(String[] args) {
        List<SoftReference<byte[]>> list = new ArrayList<>();

        // 引用队列
        ReferenceQueue<byte[]> queue = new ReferenceQueue<>();

        for (int i = 0; i < 5; i++) {
            // 关联了引用队列, 当软引用所关联的 byte[]被回收时,软引用自己会加入到 queue 中去
            SoftReference<byte[]> ref = new SoftReference<>(new byte[_4MB], queue);
            System.out.println(ref.get());
            list.add(ref);
            System.out.println(list.size());
        }

        // 从队列中获取无用的 软引用对象,并移除
        Reference<? extends byte[]> poll = queue.poll();
        while( poll != null) {
            list.remove(poll);
            poll = queue.poll();
        }

        System.out.println("===========================");
        for (SoftReference<byte[]> reference : list) {
            System.out.println(reference.get());
        }

    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值