• Java Reference


    概述

    Java中一共有四种Reference, 其中 SoftReference, WeakReference, PhantomReference内有一个Referent和ReferenceQueue

    • Referent: 被引用对象
    • RefernceQueue: 当引用的Referent被回收后该引用会被enqueue到这个ReferenceQueue中

    一个对象可以同时拥有多种引用, 可以通过Reference.get()方法获取Referent

    StrongReference (强引用)

    强引用时Java中使用得最多的引用, 我们使用的普通引用就是Java强应用例如

    Object o = new Object();

    o就是一个强引用, 强引用不会被JVM GC, 即使内存不够抛出OutOfMemoryError也不会被回收  

    SoftReference (软引用)

    软引用是Java中一个类, 它的Referent只有在内存不够的时候在抛出OutOfMemoryError前会被 JVM GC, 软引用一般用来实现内存敏感缓存(memory-sensitive caches)

    软引用可以和一个ReferenceQueue一起使用, 当SoftReference的Referent被回收以后,这个SoftReference会被自动enqueue到这个queue中,如下: 

    ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
    SoftReference<Object> softReference = new SoftReference<Object>(o, queue);

    WeakReference (弱引用)

    弱引用相较于软引用生命周期更弱, 当一个对象仅有一个弱引用时它的Referent会在JVM GC执行以后被回收, 但是由于GC线程(如 System.gc())是一个低优先级线程,手动调用System.gc()未必会立即执行GC, 因此弱引用的Referent不一定会马上被回收.同样, 弱引用也可以和一个ReferenceQueue共同使用

    Object o = new Object();
    ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
    WeakReference<Object> ref = new WeakReference<Object>(o, queue);
    o = null;
    System.out.println(ref.get());
    System.gc();
    System.out.println(ref.get());

    输出

    java.lang.Object@1a758cb
    null

    PhantomReference (虚引用)

    虚引用不会影响对象的生命周期, 他仅仅是一个对象生命周期的一个标记, 他必须与ReferenceQueue一起使用, 构造方法必须传入ReferenceQueue, 因为它的作用就是在对象被JVM决定需要GC后, 将自己enqueue到RQ中. 他通常用来在一个对象被GC前作为一个GC的标志,以此来做一些finalize操作

    另外,PhantomReference.get()方法永远返回null

    ReferenceQueue (引用队列)

    如果Reference在构造方法加入ReferenceQueue参数, Reference在它的Referent被GC的时,会将这个Reference加入ReferenceQueue

    WeakHashMap

    WeakHashMap是HashMap的WeakReference实现, 他使用WeakReference封装了Entry的Key,  如果这个WeakHashMap的key仅有这个Map持有弱引用,则当JVM GC执行时,它的key和value会被GC. 如果这个key还有别的引用则不会被GC.

    WeakHashMap<Object, String> map = new WeakHashMap<Object, String>();
    map.put(new Object(), "test");
    System.out.println(map);
    System.gc();
    System.out.println(map);

    输出

    {java.lang.Object@1a758cb=test}
    {}

  • 相关阅读:
    IntelliJ IDEA 如何在同一个窗口创建多个项目--超详细教程
    spring IOC原理
    java工作错误总结
    java跬步积累
    简单易懂设计模式——简单工厂模式
    Argo 项目入驻 CNCF,一文解析 Kubernetes 原生工作流
    电子书下载 | 超实用!阿里售后专家的 K8s 问题排查案例合集
    在生产环境中,阿里云如何构建高性能云原生容器网络?(含 PPT 下载)
    SIG Cloud Provider Alibaba 网研会第 2 期顺利召开 | 云原生生态周报 Vol. 46
    提问赠书 | 我们请了 7 位云原生专家,等你来问
  • 原文地址:https://www.cnblogs.com/zemliu/p/3333499.html
Copyright © 2020-2023  润新知