精华内容
下载资源
问答
  • 如何判断强软弱虚这几种引用?
    2021-03-10 00:30:58

    软引用、弱引用、虚引用,全都继承自同一个抽象类,这个抽象类Reference,这个抽象类实现了引用类的主要方法,另外三个对它的扩展很少。

    看了一下 java 8 的源码

    软引用只是添加了个时间戳,弱引用什么都没添加,虚引用只是把返回返回值直接定为null。

    而原本的那个对象,被传参给了抽象类Reference的构造函数,然后成为了它的一个成员,是个强引用。

    我原本还觉得引用类的实现需要交给 native 层,一看源码发现并不是。

    由于这个 Reference 存储了一个强引用,所以凭直觉它应该是无法被 GC 的,但是 Reference 源码里的很多地方都写道,将在 GC 时被修改。

    既然对 Reference 的这个强引用成员置 null 的过程是在 GC 的时候,所以我个人猜测一下(确实对 jvm 的研究非常有限,所以只敢猜测只敢设想),也许在有些 jvm 的实现中,可能是在 Full GC 标记对象的时候,遇到 Reference 时就把这个 Reference 加入一个集合,但是不标记它所引用的对象,当除 Reference 外其它的所有强引用的对象都标记过后,再遍历这个 Reference 集合,如果被引用的对象尚未标记,即已经不存在其余强引用,再对 Reference 做出相应的操作,其中就包括将内部强引用置 null,所有 Reference 处理完成后再统一销毁未标记的对象。

    我个人认为,对于能否查看一个对象的所有引用,应该不是一种需要实现的标准,因为它是非常依赖 jvm 具体实现的,毕竟引用类型关乎到了 GC 的实现方式。

    况且,一个对象完全可以同时在各个线程被许许多多不同类型的引用所引用,这样的话,如果不检验可达性,恐怕很难判断一个对象此时的最高引用类型是哪一种,而检验可达性则是一个非常耗时的过程。

    更多相关内容
  • 前言java中的引用类型共4种:强软弱虚,具体每种类型的特点和应用场景。记录下。本文是看了马士兵老师的视频后记录整理的。加深印象。基本概念1. 强引用强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾...

    前言

    java中的引用类型共4种:强软弱虚,具体每种类型的特点和应用场景。记录下。本文是看了马士兵老师的视频后记录整理的。加深印象。

    基本概念

    1. 强引用

    强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足时,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。

    c4d7b278d26e4e7ef5571b3dcefee871.png

    显式地设置M对象为null,或让其超出对象的生命周期范围,则gc认为该对象不存在引用,这时就可以回收这个对象

    示例代码

    声明一个M类

    public class M {

    /**

    * 当这个对象会被回收的时候,finalize会被调用

    *

    * @throws Throwable

    */

    @Override

    protected void finalize() throws Throwable {

    System.out.println("finalize");

    }

    }

    强引用调用

    public class NormalReference {

    public static void main(String[] args) throws IOException {

    M m = new M();

    m = null;

    System.gc();

    // 如果不写 main方法退出。System.gc()在垃圾回收线程里;

    // 有可能还没来得及回收main方法就退出了

    System.in.read();

    }

    }

    输出结果

    finalize

    2. 软引用

    软引用对象是在jvm内存不够的时候才会被回收

    5f454d5df1755de62fc905138a12263f.png

    代码示例

    public class Soft {

    public static void main(String[] args) {

    System.out.println(Runtime.getRuntime().totalMemory() / 1024 / 1024);

    //10m

    SoftReference m = new SoftReference<>(new byte[1024 * 1024 * 10]);

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

    System.gc();

    try {

    Thread.sleep(1500);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

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

    // 再分配一个数组,heap装不下去,这时候系统会垃圾回收,

    // 先回收一次,如果不够,会把软引用回收

    byte[] b = new byte[1024 * 1024 * 11];

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

    }

    }

    设置程序运行参数: -Xmx20M

    运行结果

    19

    [B@1540e19d

    [B@1540e19d

    null

    我们可以看到,这个时候已经被回收了。

    应用场景:软引用时候做缓存

    3. 弱引用

    弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存

    代码示例

    public class Weak {

    public static void main(String[] args) {

    WeakReference m = new WeakReference<>(new M());

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

    System.gc();

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

    }

    }

    执行结果

    M@1540e19d

    null

    finalize

    4. 虚引用

    如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。

    虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。

    d74cc473d492bf7bb04e10572beb7dcb.png

    示例

    public class Phantom {

    private static final List LIST = new LinkedList<>();

    private static final ReferenceQueue QUEUE = new ReferenceQueue<>();

    public static void main(String[] args) {

    PhantomReference phantomReference = new PhantomReference<>(new M(), QUEUE);

    new Thread(

    () -> {

    while (true) {

    LIST.add(new byte[1024 * 1024]);

    try {

    Thread.sleep(1000);

    } catch (InterruptedException e) {

    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();

    }

    }

    运行结果

    finalize

    null

    Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space

    at Phantom.lambda$main$0(Phantom.java:18)

    at Phantom$$Lambda$1/1078694789.run(Unknown Source)

    at java.lang.Thread.run(Thread.java:748)

    -------虚引用对象被jvm回收了------java.lang.ref.PhantomReference@688ee48d

    应用场景:堆外内存的管理

    总结

    到此这篇关于java中引用类型之强软弱虚的文章就介绍到这了,更多相关java引用类型之强软弱虚内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    展开全文
  • 强软弱虚四种引用介绍

    千次阅读 2020-10-29 18:56:21
    强软弱虚四种引用 1.强 User u = new User() 正常写的引用都是强引用,JVM会根据是否可达判断是否要回收。 2.软 SoftReference<byte[]> res = new SoftReference<>(new byte[1024]); res里面的byte...

    强软弱虚四种引用

    1.强

    User u = new User()
    

    正常写的引用都是强引用,JVM会根据是否可达判断是否要回收。

    2.软

    SoftReference<byte[]> res = new SoftReference<>(new byte[1024]);
    

    res里面的byte数组是软引用。只被软引用关联着的对象,在系统将要发生内
    存溢出异常前,会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够的内存,才会抛出内存溢出异常。
    用途: 缓存信息。

    3.弱引用

    WeakReference<Object> m = new WeakReference();
    System.out.println(m.get());
    

    只要GC,就会被回收。
    用途: ThreadLocal。

    先简单介绍一下ThreadLocal:每个线程都有一个ThreadLocalMap。ThreadLocalMap的key是ThreadLocal,value是我们要存储的值。spring的@Transactional就是利用ThreadLocal。连接数据库需要用同一个connection(保证是在同一个事务中),所以不同线程的connection不能共用,独有一份connection,这时就用到了ThreadLocal。

    下面是ThreadLocal里面Map用的Entry:

    static class Entry extends WeakReference<ThreadLocal<?>> {
                /** The value associated with this ThreadLocal. */
                Object value;
    
                Entry(ThreadLocal<?> k, Object v) {
                    super(k);
                    value = v;
                }
            }
    

    能看出entry是个弱引用,那么为什么要用弱引用呢?
        如果线程里没有人再使用ThreadLocal,那么如果ThreadLocalMap的Key是个强引用,这个Map永远不会被回收(只有线程销毁时才回收)。还有一点要注意,如果ThreadLocal被回收了之后,ThreadLocalMap的Value还会保持引用,而key为null。如果线程不结束,不会被自动回收,所以需要手动remove。

    4.虚引用

    ReferenceQueue<Object> queue = new ReferenceQueue();
    PhantomReference<Object> m = new PhantomReference(new Object(),queue);
    

    虚引用的m.get()永远无法得到对象,永远都是null。
    用途: 虚引用的唯一作用是管理堆外内存,因为JVM无法直接清理堆外内存,所以提供一个虚引用,交给垃圾回收器的回收队列,这个队列就是用来标记哪些堆外内存需要回收,再调用c++释放空间。

    展开全文
  • Java中的强软弱虚

    2018-06-27 14:10:47
    从JDK1.2版本开始,把对象引用分别四中级别,从而使程序能更加灵活的控制对象的生命周期,四中级别由高到低依次为:引用、软引用、弱引用和引用。1、引用: 比如 Object object=new Object(); new 创建出来的...

        从JDK1.2版本开始,把对象引用分别四中级别,从而使程序能更加灵活的控制对象的生命周期,四中级别由高到低依次为:强引用、软引用、弱引用和虚引用。

    1、强引用:

        比如 Object object=new Object(); new 创建出来的object 对象就是强引用。当内存空间不足时,Java虚拟机宁愿抛出OutOfMemoryError错误,是程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。

    2、软引用(SoftReference):

        如果一个对象是软引用,如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可以用来实现内存敏感的高速缓存。软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

    3、弱引用(WeakReference):

        弱引用和软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内容区域的过程中,一旦发现了只具有弱引用对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些具有弱引用的对象。弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

    4、虚引用(PhantomReference):

        “虚引用”顾名思义,就是形同虚设的意思,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。虚引用主要用来跟踪对象被垃圾回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

    5、相关应用

        在java.lang.ref包中提供了三个类:SoftReference类、WeakReference类和PhantomReference类,它分别代表软引用、弱引用和虚引用。ReferenceQueue类表示引用队列,它可以和这三种引用类联合使用,以便跟踪Java虚拟机回收所引用的对象的活动。

        1)先看一段代码

    //创建一个强引用
    String str=new String("hello");//1
    //创建引用队列;表明队列中存放String对象的引用ReferenceQueue;
    ReferenceQueue rq=new ReferenceQueue();//2
    //创建一个弱引用,它引用"hello"对象,并且与rq引用队列关联 表明WeakReference会弱引用String对象
    WeakReference wf=new WeakReference(str,rq);//3
    

      以上代码执行完毕,内存中引用与对象的关系如图所示:


                            图1   “hello” 对象同时具有强引用和弱引用

       上图中实线表示强引用,虚线表示弱引用。由图看出,"hello"对象被str强引用,并且被一个WeakReference弱引用,因此“hello”对象不会被垃圾回收。

        2)在以下程序代码中,把引用“hello”对象变量设置为null,然后再通过WeakReference弱引用的get()方法获得“hello”对象的引用:

    String str=new String("hello");//1
    //创建引用队列;表明队列中存放String对象的引用ReferenceQueue;
    ReferenceQueue rq=new ReferenceQueue();//2
    //创建一个弱引用,它引用"hello"对象,并且与rq引用队列关联 表明WeakReference会弱引用String对象
    WeakReference wf=new WeakReference(str,rq);//3
    str=null;//4 取消"hello" 对象的强引用
    String str1= (String) wf.get();//5 假如“hello”对象没有被回收,str1引用“hello”对象;
    // 假如“hello”对象没有被回收,rq.poll()返回null
    Reference ref=rq.poll();//6
    执行完第四行后,内存中引用与对象的关系如下图所示:


        图2 “hello”对象仅仅具有弱引用

    因此他有可能会被垃圾回收。假如他还没有被垃圾回收,那么接下来第5行代码执行wf.get()方法会返回“hello”对象的引用,并且使得对象被强引用。在接下来第6行执行rq.poll() 方法会返回null,因为此时引用中没有任何引用。ReferenceQueue的poll()方法用于返回队列中的引用,如果没有则返回null。

        3)先看代码

    //创建一个强引用
    String str=new String("hello");//1
    //创建引用队列;表明队列中存放String对象的引用ReferenceQueue;
    ReferenceQueue rq=new ReferenceQueue();//2
    //创建一个弱引用,它引用"hello"对象,并且与rq引用队列关联 表明WeakReference会弱引用String对象
    WeakReference wf=new WeakReference(str,rq);//3
    str=null;//4 取消"hello" 对象的强引用
    //两次催促垃圾回收器工作,提高“hello”对象被回收的可能
    System.gc();//5
    System.gc();//6
    String str1= (String) wf.get();//7 假如“hello”对象没有被回收,str1引用“hello”对象;
    // 假如“hello”对象没有被回收,rq.poll()返回null
    Reference ref=rq.poll();//8

    在以上程序代码中,在执行完第4行代码后,“hello”对象仅仅具有弱引用。接下来两次调用System.gc()方法,催促垃圾回收器工作,从而提高“hello” 对象被回收的可能性。假如“hello”对象被回收,那么WeakReference对象的引用被加入到ReferenceQueue中,接下来wf.get()方法返回null,并且rq.poll()方法返回WeakReference对象的引用。图3显示执行了第8行代码后内存中引用与对象的关系。


        图3 "hello" 对象被垃圾回收,弱引用被加入到引用队列


        4)继续先看代码

    package com.lixm.animationdemo.bean;
    
    import org.xutils.common.util.LogUtil;
    
    /**
     * Describe:
     * <p>
     *     强软弱虚创建对象
     *
     * Author: Lixm
     * Date: 2018/6/27
     */
    public class Grocery {
        private String TAG=getClass().getName();
        private static final int SIZE=10000;
        //属性d使得每个Grocery对象占用较多的内存,有80k左右
        private double[] d=new double[SIZE];
        private String id;
    
        public Grocery(String id) {
            this.id = id;
        }
    
        public String toString(){
            return id;
        }
    
        public void finalize(){
            LogUtil.i(TAG,"Finalizing "+id);
        }
    }
    /**
     * Describe:
     * <p>
     * 强软弱虚创建对象
     * Author: Lixm
     * Date: 2018/6/27
     */
    public class References {
        private static String TAG = "References";
    
        private static ReferenceQueue rq = new ReferenceQueue();
    
        public static void checkQueue() {
            Reference inq = rq.poll();
            //从队列中取出一个引用
            if (inq != null) {
                LogUtil.i(TAG, "In queue: " + inq + " : " + inq.get());
            }
        }
    
        public static void main(String[] args) {
            final int size = 10;
            //创建10Grocery对象,以及10个软引用
            Set sa = new HashSet();
            for (int i = 0; i < size; i++) {
                SoftReference ref = new SoftReference(new Grocery("soft" + i), rq);
                LogUtil.i(TAG, "Just created soft: " + ref.get());
                sa.add(ref);
            }
            System.gc();
            checkQueue();
    
            LogUtil.i(TAG,"---------------------------------");
            //创建10Grocery对象以及10个弱引用
            Set wa=new HashSet();
            for (int i=0;i<size;i++){
                WeakReference ref=new WeakReference(new Grocery("weak"+i),rq);
                LogUtil.i(TAG,"Just created weak: "+ref.get());
                wa.add(ref);
            }
            System.gc();
            checkQueue();
    
            System.out.println("=============================");
            //创建10Grocery对象,以及10个虚引用
            Set pa=new HashSet();
            for (int i=0;i<size;i++){
                PhantomReference ref=new PhantomReference(new Grocery("Phantom "+i),rq);
                System.out.println("Just created Phantom :"+ref.get());
                pa.add(ref);
            }
            System.gc();
            checkQueue();
        }
    }
    
    

    打印结果为:

    Just created soft: soft0Just created soft: soft1Just created soft: soft2Just created soft: soft3Just created soft: soft4Just created soft: soft5Just created soft: soft6Just created soft: soft7Just created soft: soft8Just created soft: soft9---------------------------------Just created weak: weak0Just created weak: weak1Just created weak: weak2Just created weak: weak3Just created weak: weak4Just created weak: weak5Just created weak: weak6Just created weak: weak7Just created weak: weak8Just created weak: weak9-----------------------------------------------Finalizing weak9Finalizing weak8Finalizing weak6Just created Phantom :nullFinalizing weak7Just created Phantom :nullFinalizing weak0Finalizing weak1Just created Phantom :nullFinalizing weak4Finalizing weak5Just created Phantom :nullFinalizing weak2Just created Phantom :nullJust created Phantom :nullFinalizing weak3Just created Phantom :nullJust created Phantom :nullJust created Phantom :nullJust created Phantom :nullFinalizing Phantom 4Finalizing Phantom 2Finalizing Phantom 1Finalizing Phantom 3Finalizing Phantom 6Finalizing Phantom 5Finalizing Phantom 7Finalizing Phantom 9Finalizing Phantom 8Finalizing Phantom 0In queue: java.lang.ref.WeakReference@232204a1 : null

    在以上References类中,依次创建了10个软引用,10个弱引用和10个虚引用,他们各自引用一个Grocery对象。从程序运行时打印的结果可以看出,虚引用形同虚设,他所引用的对象随时可能被垃圾回收;具有弱引用的对象拥有稍长的生命周期,当垃圾回收器执行回收操作时,有可能被垃圾回收;具有软引用的对象拥有较长的生命周期,但在Java虚拟机认为内容不足的情况下,也会被垃圾回收。

    5)在Java集合中有一种特殊的Map类型:WeakHashMap,在这种Map中存放了键对象的弱引用,当一个键对象被垃圾回收,那么相应的值对象的引用会从Map中删除。WeakHashMap能够节约存储空间,可用来缓存那些非必须存放的数据。

        以下代码MapCache类的main()方法创建了一个WeakHashMap对象,它存放了一组Key对象的弱引用,此外main()方法还创建了一个数组对象,它存放了部分key对象的强引用。

    package com.lixm.animationdemo.bean;
    
    /**
     * Describe:
     * <p>
     * Author: Lixm
     * Date: 2018/6/27
     */
    public class Key {
        private String id;
    
        public Key(String id) {
            this.id = id;
        }
    
        public String toString (){
            return id;
        }
    
        public int hashCode(){
            return id.hashCode();
        }
    
        public boolean equals(Object r){
            return (r instanceof Key) && id.equals(((Key)r).id);
        }
    }
    package com.lixm.animationdemo.bean;
    
    /**
     * Describe:
     * <p>
     * Author: Lixm
     * Date: 2018/6/27
     */
    public class Value {
        private String id;
    
        public Value(String id) {
            this.id = id;
        }
    
        public String toString() {
            return id;
        }
    
        public void finalize() {
            System.out.println("Finalizing Value " + id);
        }
    }
    package com.lixm.animationdemo.bean;
    
    import java.util.Scanner;
    import java.util.WeakHashMap;
    
    /**
     * Describe:
     * <p>
     * Author: Lixm
     * Date: 2018/6/27
     */
    public class MapCache {
        public static void main(String[] args)throws Exception{
    //        int size=1000;//或者从命令行获得Size的大小
            System.out.println("请输入size大小:");
            Scanner sc=new Scanner(System.in);
            String sizeStr=sc.next();
            int size=Integer.parseInt(sizeStr);
            if (args.length>0) {
                size = Integer.parseInt(args[0]);
            }
            Key[] keys=new Key[size];//存放键对象的强引用
            WeakHashMap whm=new WeakHashMap();
            for (int i=0;i<size;i++){
                Key k=new Key(Integer.toString(i));
                Value v=new Value(Integer.toString(i));
                if (i%3==0){
                    keys[i]=k;//使key对象持有强引用
                }
                whm.put(k,v);//key对象持有弱引用
            }
            //催促垃圾回收器工作
            System.gc();//CPU让给垃圾回收器线程
            Thread.sleep(8000);
        }
    }

    打印结果为:

    Finalizing Key 82
    Finalizing Key 7
    Finalizing Key 5
    Finalizing Key 4
    Finalizing Key 2
    Finalizing Key 1
    Finalizing Key 20
    Finalizing Key 19
    Finalizing Key 17
    Finalizing Key 16
    Finalizing Key 14
    Finalizing Key 13
    Finalizing Key 11
    Finalizing Key 10
    Finalizing Key 8
    Finalizing Key 34
    Finalizing Key 32
    Finalizing Key 31
    Finalizing Key 29
    Finalizing Key 28
    Finalizing Key 26
    Finalizing Key 25
    Finalizing Key 23
    Finalizing Key 22
    Finalizing Key 98
    Finalizing Key 97
    Finalizing Key 95
    Finalizing Key 94
    Finalizing Key 92
    Finalizing Key 91
    Finalizing Key 89
    Finalizing Key 88
    Finalizing Key 47
    Finalizing Key 46
    Finalizing Key 44
    Finalizing Key 43
    Finalizing Key 41
    Finalizing Key 40
    Finalizing Key 38
    Finalizing Key 37
    Finalizing Key 35
    Finalizing Key 61
    Finalizing Key 59
    Finalizing Key 58
    Finalizing Key 56
    Finalizing Key 55
    Finalizing Key 53
    Finalizing Key 52
    Finalizing Key 50
    Finalizing Key 49
    Finalizing Key 74
    Finalizing Key 73
    Finalizing Key 71
    Finalizing Key 70
    Finalizing Key 68
    Finalizing Key 67
    Finalizing Key 65
    Finalizing Key 64
    Finalizing Key 62
    Finalizing Key 86
    Finalizing Key 85
    Finalizing Key 83
    Finalizing Key 80
    Finalizing Key 79
    Finalizing Key 77

    Finalizing Key 76

    从打印结果看出,当执行System.gc()方法后,垃圾回收器只会回收那么仅仅持有弱引用的Key对象。id可以被3整除的key对象持有强引用,因此不会被回收。

    6、如何使用软引用

    SoftReference的特点是他的一个实例保存对一个Java对象的软引用,该软引用的存在不妨碍垃圾收集线程对该Java对象的回收,也就是说,一旦SoftReference保存了对一个Java对象的软引用后,在垃圾线程对这个Java对象回收前,SoftReference类所提供的get()方法返回Java对象的强引用。另外,一旦垃圾线程回收该Java对象只有,get方法将返回null。

    Grocery grocery=new Grocery("Soft");
    SoftReference aSoft=new SoftReference(grocery);

    此时对于Grocery对象,有两个引用路径,一个是来自SoftReference对象的软引用,一个来自变量aReference的强引用,所以这个Grocery对象是强引用对象。

    随即,我们可以结束aReference对这个Grocery实例的强引用:

    grocery=null;

    在回收这些对象之前,我们可以通过:

    Grocery anotherRef=(Grocery) aSoft.get();

    重新获得对该实例的强引用。而回收之后,调用get()方法就只能得到null了。清除SoftReference对象:  

    SoftReference ref=null;
    while((ref =  (SoftReference) rq.poll()) != null) {
        //清除ref
    }

    熟悉了解了ReferenceQueue的工作机制之后,我们就可以开始构造一个Java对象的告诉缓存器了。

        7、用WeakHashMap堵住泄露

        在SocketManager中防止泄露很容易,只要用WeakHashMap代替HashMap就行了。(这里假定SocketManager不需要线程安全)。当映射的生命周期必须与键的生命期联系在一起时,可以使用这种方法,用WeakHashMap修复SocketManager。

    /**
     * Describe:
     * <p>
     * Author: Lixm
     * Date: 2018/6/27
     */
    public class SocketManager {
        private Map m=new WeakHashMap();
        public void setUser(Socket s,User u){
            m.put(s,u);
        }
        public User getUser(Socket s){
            return (User) m.get(s);
        }
    }

    至此,大致了解了Java中的强软弱虚引用,选择合适的引用,已完成更高效的程序开发。

    本文参考:点击打开链接 谢谢

    展开全文
  • Java的四种引用类型-强软弱虚强引用软引用弱引用虚引用 强引用 软引用 弱引用 虚引用
  • 强软弱虚java中的数据被类型分为了两类,它们分别是基本类型和引用类型。一般我们new出来的对象都属于引用类型的范畴。我们知道java是有垃圾回收机制的一种语言,根据垃圾回收时的策略,java将对于堆对象的引用又...
  • 回想了一下,上次学习Java的强软弱虚四种引用类型,还是在准备面试的时候。平时用得不多,一下子竟然想不清楚它们的区别,只记得它们的强度依次递减。 下来又看了一下这方面的文章,今天好好把它们理清楚。 四种...
  • 强软弱虚四种引用

    2020-08-11 22:55:39
    四种引用类型 所以在 JDK.1.2 之后,Java 对引用的概念进行了扩充,将引用分为了:引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、引用(Phantom Reference)4 种,这 4 种...
  • 引用二、引用:1. 正常创建的对象,只要引用存在,永远不会被GC回收,即使OOMObject obj = new Object();2. 如果要中断引用和某个对象的关联,为其赋值null,这样GC就会在合适的时候回收对象3. Vector类的...
  • 强软弱虚引用区别

    2020-03-24 00:49:08
    1 引用 特点:我们平常典型编码Object obj = new Object()中的obj就是引用。通过关键字new创建的对象所关联的引用就是引用。 当JVM内存空间不足,JVM宁愿抛出OutOfMemoryError运行时错误(OOM),使程序异常...
  • 引用、软引用、弱引用、引用这四个概念非常简单好记!用几个示例代码感受一下吧。
  • 那么今天来详细说说强软弱虚这四个引用方式以及GC是背后是怎么处理的。 强引用 普通的应用类型,只要有引用指针,GC不会回收 ,例如:Student student = new Student,想要让GC检测并回收此对象,你需要让它引用...
  • java中的引用类型共4种:强软弱虚,具体每种类型的特点和应用场景。记录下。本文是看了马士兵老师的视频后记录整理的。加深印象。基本概念1. 强引用强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器...
  • Java强软弱虚引用

    2019-08-12 18:56:31
    引用: Test test1 = new Test(); 程序中普遍存在的,GC Roots独享指向的引用都属于引用,只要当前对象被任意一个引用指向,即便内存不够用也不能够回收此对象。 软引用: public class Test4 { private ...
  • 引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、引用(Phantom Reference)总结:引用:不管内存够不够都不会被回收(我们平时new创建对象就是引用)软引用:内存够用不回收,不够用...
  • 深入理解Java中的引用(二)——强软弱虚引用在上一篇文章中介绍了Java的Reference类,本篇文章介绍他的四个子类:强引用、软引用、弱引用、虚引用。强引用(StrongReference)强引用是我们在代码中最普通的引用。示例...
  • 引用-FinalReference 介绍: 引用是平常中使用最多的引用,引用在程序内存不足(OOM)的时候也不会被回收,使用方式: Stringstr =newString("str"); 这个str就是引用。 软引用-SoftReference 介绍...
  • 强软弱虚四大引用

    2021-04-07 18:44:01
    强软弱虚四大引用1 概述2 强引用2.1 垃圾回收方式2 .2 代码实例3 软引用3.1 垃圾回收方式3.2 代码实例4 弱引用4.1 垃圾回收方式4.2 代码实例4.3 使用场景4.4 WeakHashMap4.4.1 代码示例5 虚引用5.1 回收方式5.2 代码...
  • 引用 特点:我们平常典型编码Object obj = new Object()中的obj就是引用。通过关键字new创建的对象所关联的引用就是引用。 当JVM内存空间不足,JVM宁愿抛出OutOfMemoryError运行时错误(OOM),使程序异常...
  • Java中的强软弱虚引用

    2011-09-27 15:50:37
    笔者自己的通俗总结,5分钟搞清楚java中强软弱虚引用的区别^_^
  • Java强软弱虚4大引用

    2017-11-27 16:46:16
    概念:System.gc(),实际上System.gc()调用的又是 ...强软弱虚。这4个引用出现的背景实际上就是为了我们在一定程度上对gc的可控,让它变得尽量的符合我们对内存分配的预期。强引用:强引用就是Object o = new Object()
  • jvm之强软弱虚引用

    万次阅读 2020-07-16 19:58:56
    强软弱虚引用 在java中,除了基本数据类型的变量外,其他所有的变量都是引用类型,指向堆上各种不同的对象。 在jvm中,除了我们常用的强引用外,还有软引用、弱引用、虚引用,这四种引用类型的生命周期与jvm的垃圾...
  • 因此,在JDK1.2之后Java对引用的概念进行了扩充,将引用分为引用(Strong Reference),软引用(Soft Reference),弱引用(Weak Reference),引用(Phantom Reference)4种 这4种引用强度依次逐渐减弱。这里的引用...
  • 在JDK1.2之后,Java对引用的概念进行了扩充,将引用分成强引用、软引用、弱引用和虚引用(强软弱虚)。这四种的引用强度依次减弱。除了强引用之外,其他三种引用均可以在java.lang.ref包下。引用的顶层接口为Reference...
  • JVM垃圾回收,参数,强软弱虚,常见错误OOM,与微服务结合.docx
  • 以前学习强软弱虚引用的时候,只是走马观花看看博客,并没有自己写代码去实践、去证明,导致每次看完后,过不了多久就忘了,后来下定决心,一定要自己敲敲代码,这样才能让印象更加深刻,古人云:纸上得来终觉浅,...
  • 引用 Object o = new Object();这就是引用,只要某个对象有引用与之关联,这个对象永远不会被回收,即使内存不足,JVM宁愿抛出OOM,也不回去回收,只有当引用和对象之间的关联切断了,就可以被回收了,回收...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,247
精华内容 898
关键字:

强软弱虚

友情链接: 483672.rar