美文网首页
强软弱虚引用

强软弱虚引用

作者: CodeYang | 来源:发表于2022-11-01 19:11 被阅读0次

    强引用

    简介:

    强引用 (Strong Reference)

    特征:

    只有手动赋值为 null 才会被垃圾回收线程回收

    实验:

    创建一个对象(对比两者输出):未置空,调用垃圾线程进行回收;置空,调用垃圾线程进行回收

    结果:

    当对象未置空,并没有输出垃圾回收时才会调用的方法;对象置空,并输出垃圾回收时才会调用的方法;

    实验代码:
    public class T01_M {
    
        /**
         * 线程机型垃圾回收时,会调用该方法
         * @throws Throwable
         */
        @Override
        protected void finalize() throws Throwable {
            super.finalize();
            System.out.println("T01_M被垃圾回收线程,回收"+this);
        }
    }
    
    public class T01_StrongReference {
        public static void main(String[] args) {
            T01_M m = new T01_M();
            System.out.println("未置空对象,调用垃圾回收线程,回收");
            System.gc();
            System.out.println("置空对象,调用垃圾回收线程,回收");
            m = null;
            System.gc();
        }
    }
    
    实验结果:
    image.png

    软引用

    简介:

    软引用 (Soft Reference)

    特征:

    在堆内存不足时,系统则会回收软引用对象,
    如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常。

    用途:

    主要用于缓存上面

    实验:

    准备:(设置JVM启动参数:-Xmx20M; 使用JDK11,使用JDK8时,会OOM,暂不清楚原因)

    • 1.设置堆大小 20M,创建软引用对象占用10M;
    • 2.调用垃圾回收线程,输出软引用,发现并未回收掉软引用对象;
    • 3.创建bytes数组 占用 15M;堆最大 20M(剩余10M),正常情况下会发生OOM的情况;但是因为是软引用对象;当堆内存不够时,会自动回收软引用对象
    • 4.再次输出 软引用对象,发现为空,说明已经被垃圾回收线程回收
    结果:

    当正常分配对象堆内存时,发现堆内存不足以分配新空间时,会回收软引用对象

    idea 启动配置
    image.png
    实验代码:
    public class T02_SoftReference {
        public static void main(String[] args) {
            SoftReference<byte[]> m = new SoftReference<>(new byte[1024 * 1024 * 10]);
            System.out.println("垃圾回收前:"+m.get());
            System.gc();
            System.out.println("垃圾回收(堆内存足够):"+m.get());
            byte[] bytes = new byte[1024 * 1024 * 15];
            System.out.println("垃圾回收(堆内存不足):"+m.get());
        }
    }
    
    实验结果:
    image.png

    弱引用

    简介:

    软引用 (Weak Soft)

    特征:

    经历垃圾回收,弱引用对象必会被回收;一次性使用
    JVM 进行垃圾回收,一旦发现弱引用对象,无论当前内存空间是否充足,都会将弱引用回收。

    用途:

    ThreadLocal

    实验:

    创建弱引用对象,调用垃圾回收线程回收,观察弱引用对象是否被清理

    结果:

    弱引用对象京过垃圾回收线程之后,被回收

    实验代码:
    public class T03_WeakReference {
    
        public static void main(String[] args) {
            WeakReference<Object> m = new WeakReference<>(new Object());
    
            System.out.println(m.get());
            System.gc();
            System.out.println(m.get());
        }
    }
    
    实验结果:
    image.png

    虚引用

    简介:

    虚引用 (Phantom Reference)
    虚引用必须和引用队列 (ReferenceQueue)联合使用
    当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中.
    你可以通过判断queue里面是不是有对象来判断你的对象是不是要被回收了

    实验代码:
    public class T04_PhantomReference {
        private static final List<Object> LIST = new LinkedList<>();
        private static final ReferenceQueue<T04_M> QUEUE = new ReferenceQueue<>();
    
        public static void main(String[] args) {
            PhantomReference<T04_M> phantomReference = new PhantomReference<>(new T04_M(),QUEUE);
    
            new Thread(()->{
               while (true){
                   LIST.add(new byte[1024*1024]);
                   try {
                       Thread.sleep(1000);
                   } catch (InterruptedException e) {
                       throw new RuntimeException(e);
                   }
                   System.out.println(phantomReference.get());
               }
            }).start();
    
            new Thread(()->{
                while (true){
                    Reference<? extends T04_M> poll = QUEUE.poll();
                    if(poll!=null){
                        System.out.println("======虚引用对象被JVM 回收了======"+poll);
                    }
                }
            }).start();
    
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
    
    

    相关文章

      网友评论

          本文标题:强软弱虚引用

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