美文网首页
Java对象4种引用的回收

Java对象4种引用的回收

作者: zhaozhaoicode | 来源:发表于2020-05-08 22:54 被阅读0次

Java对象的4种引用对应的回收

  • 强 肯定是不会被回收的
  • 软 jvm内存不够用的时候会就会回收
  • 弱 发生gc的时候,只要看到这种引用就会被回收
  • 虚 这种引用无法被访问到,主要写jvm处理堆回收使用
/**
 * 为了方便测试观察对象回收,重写下finalize
 */
public class M {
    @Override
    protected void finalize() throws Throwable {
        System.out.println("finalize");
    }
}

/** 
 * 强引用
 */
public class TestNormalReference {
    public static void main(String[] args) throws IOException {
        M m = new M();
        // m = null; 手动释放
        System.gc(); //DisableExplicitGC
        System.out.println(m);
        System.in.read(); 
    }
}

/**
 * 软引用
 * 软引用是用来描述一些还有用但并非必须的对象。
 * 对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围进行第二次回收。
 * 如果这次回收还没有足够的内存,才会抛出内存溢出异常。
 * -Xmx20M
 */
import java.lang.ref.SoftReference;

public class TestSoftReference {

    public static void main(String[] args) {
        SoftReference<byte[]> m = new SoftReference<>(new byte[1024*1024*10]);
        //m = null;
        System.out.println(m.get());
        System.gc();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(m.get());

        //再分配一个数组,heap将装不下,这时候系统会垃圾回收,先回收一次,如果不够,会把软引用干掉
        byte[] b = new byte[1024*1024*15];
        System.out.println(m.get());
    }
}

/**
 * 弱引用遭到gc就会回收
 */
import java.lang.ref.WeakReference;

public class TestWeakReference {
    public static void main(String[] args) {
        WeakReference<M> m = new WeakReference<>(new M());

        System.out.println(m.get());
        System.gc();
        System.out.println(m.get());

        ThreadLocal<M> tl = new ThreadLocal<>();
        tl.set(new M());
        tl.remove();   // 不用ThreadLocal就手动remove掉,否则存放ThreadLocal的Tread.threadlocals的Map中引用对象是不会被回收的(不注意是个小坑)
    }
}

/**
 * 一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,
 * 也无法通过虚引用来获取一个对象的实例。
 * 为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。
 * 虚引用和弱引用对关联对象的回收都不会产生影响,如果只有虚引用活着弱引用关联着对象,
 * 那么这个对象就会被回收。它们的不同之处在于弱引用的get方法,虚引用的get方法始终返回null,
 * 弱引用可以使用ReferenceQueue,虚引用必须配合ReferenceQueue使用。
 *
 * jdk中直接内存的回收就用到虚引用,由于jvm自动内存管理的范围是堆内存,
 * 而直接内存是在堆内存之外(其实是内存映射文件,自行去理解虚拟内存空间的相关概念),
 * 所以直接内存的分配和回收都是有Unsafe类去操作,java在申请一块直接内存之后,
 * 会在堆内存分配一个对象保存这个堆外内存的引用,
 * 这个对象被垃圾收集器管理,一旦这个对象被回收,
 * 相应的用户线程会收到通知并对直接内存进行清理工作。
 *
 * 事实上,虚引用有一个很重要的用途就是用来做堆外内存的释放,
 * DirectByteBuffer就是通过虚引用来实现堆外内存的释放的。
 */
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.util.LinkedList;
import java.util.List;

public class TestPhantomReference {
    private static final List<Object> LIST = new LinkedList<>();
    private static final ReferenceQueue<M> QUEUE = new ReferenceQueue<>();

    public static void main(String[] args) {
        PhantomReference<M> phantomReference = new PhantomReference<>(new M(), QUEUE);

        new Thread(() -> {
            while (true) {
                LIST.add(new byte[1024 * 1024]);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    Thread.currentThread().interrupt();
                }
                System.out.println(phantomReference.get());
            }
        }).start();

        new Thread(() -> {
            while (true) {
                Reference<? extends M> poll = QUEUE.poll();
                if (poll != null) {
                    System.out.println("虚引用对象被jvm回收了" + poll);
                }
            }
        }).start();

        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
ThreadLocal弱引用 ThreadLocal set源码

相关文章

  • 深入理解Java的分级引用模型

    1 Java的引用 对于Java中的垃圾回收机制来说,对象是否被应该回收的取决于该对象是否被引用。因此,引用也是J...

  • 第三章(一)GC入门

    本篇主要讲述 JAVA与GC 、JAVA与引用 和JAVA对象回收流程 。 垃圾回收(Garbage Collec...

  • Java基础系列-强引用、弱引用、软引用、虚引用

    强引用(StrongReference) 被强引用对象引用到,是不会被垃圾回收器回收 当内存空间不足,Java虚拟...

  • 学习JVM必不可少的知识

    1.Java垃圾回收机制 对象被判断为垃圾的标准:没有被其他对象引用 2.判断对象是否可被回收 (1)引用计数算法...

  • 学习JVM必不可少的知识

    1.Java垃圾回收机制 对象被判断为垃圾的标准:没有被其他对象引用 2.判断对象是否可被回收 (1)引用计数算法...

  • 对象的引用

    一、概述 Java对象的引用:强引用,软引用,弱引用和虚引用。众所周知,Java中是JVM负责内存的分配和回收,这...

  • 强软弱虚引用

    一、强引用(StrongReference) 不会回收有强引用的对象。 除了强引用,其他的引用都需要借助java....

  • 内存泄露案例

    对象本应被GC回收的情况,由于被外部对象引用持有,导致不能被正常回收 Bean.java MainActivity...

  • 疯狂Java笔记之Java的内存与回收

    Java引用的种类 1.对象在内存中的状态 对于JVM的垃圾回收机制来说,是否回收一个对象的标准在于:是否还有引用...

  • JAVA垃圾回收

    JAVA垃圾回收 时间:20180307 问题: 如何判定对象为垃圾对象引用计数法可达性分析法 如何回收回收策略标...

网友评论

      本文标题:Java对象4种引用的回收

      本文链接:https://www.haomeiwen.com/subject/swkcnhtx.html