一个变量指向new对象,就是引用,在java中有四种引用,分别是强软弱虚,常见的Object o = new Object(),就是强引用,垃圾回收的时候,强引用不会被回收。

  •   公用类:

    public class M {
    @Override
    protected void finalize() throws Throwable {
    System.out.println("finalize");
    }
    }
  • 强:只要有引用就不会回收代码:
    public class T01_NormalReference {
    public static void main(String[] args) throws IOException {
    M m = new M();
    m = null;//只有没有引用时,M的对象m才会被回收
    System.gc(); //DisableExplicitGC
    System.in.read();//阻塞线程的目的是:因为GC是运行在其他线程中的,不阻塞很可能还没开始回收,线程就已经结束了。
    }
    }
  • 软:空间不够才回收,用于缓存
    代码:先设置VM options :-Xms20M -Xmx20M(设置堆内存最大最小都是20M)

    public class T02_SoftReference {
    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());
    }
    }
  • 弱引用:只要调用了垃圾回收(System.gc())就回收,应用场景:只要强引用消失,则应该被回收,一般用在容器里,典型应用ThreadLock,看下WeakHashMap、AQSunlock源码(Tomcat缓存用的是弱应用)
    代码:
    public class T03_WeakReference {
    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,否则还是有内存泄漏
    }
    }
  • 弱引用举例子程序
    public class ThreadLocal2 {
    static ThreadLocal<Person> tl = new ThreadLocal<>();
    public static void main(String[] args) { new Thread(()->{
    try {
    TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    tl.set(new Person());
    }).start();
    }
    static class Person {
    String name = "zhangsan";
    }
    }

    例子图示:

  • 虚引用,主要用于对外内存。一般是搞JVM的人用,所以基本没用。
    1、堆外内存。
         NIO里面有一个Buffer,叫DirectByteBuffer(直接内存,不被jvm虚拟机管理),也叫堆外内存,被操作系统管理,如果这个引用被置为空值,则没法回收,用虚引用
         时,检测Queue,如果被回收了则去清理堆外内存。java回收堆外内存用的是Unsave中的freeMemory
    2、会关联一个队列,当虚引用被回收的时候回接收到关联队列里,也就是给你一个通知,被回收了,弱引用里面的值是可以get到的,虚引用根本get不到
    3、垃圾回收器一过来,直接就被回收了
  • 验证程序(先设置堆内存为20M,VM options :-Xms20M -Xmx20M,生产环境中堆空间最大最小设置成一样)
    public class T04_PhantomReference {
    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();
    }
    }
    }

JAVA不可不知的强软弱虚四种引用的更多相关文章

  1. 5.9 j(java学习笔记)强软弱虚引用及WeakHashMap、IdentityHashMap、EnumMap

    一.引用分类 强:运行垃圾回收机制后也不回收,程序出现内存溢出也不回收. 软:在垃圾回收机制运行时判断内存是否已满,如果内存已满则回收,内存充足则不回收. 弱:垃圾回收机制运行后不论内存是否充足都会立 ...

  2. java 强弱软虚 四种引用,以及用到的场景

    1.利用软引用和弱引用解决OOM问题:用一个HashMap来保存图片的路径和相应图片对象关联的软引用之间的映射关系,在内存不足时,JVM会自动回收这些缓存图片对象所占用的空间,从而有效地避免了OOM的 ...

  3. Java中四种引用:强、软、弱、虚引用

    这篇文章非常棒:http://alinazh.blog.51cto.com/5459270/1276173 Java中四种引用:强.软.弱.虚引用 1.1.强引用当我们使用new 这个关键字创建对象时 ...

  4. Java四种引用包括强引用,软引用,弱引用,虚引用。

    Java四种引用包括强引用,软引用,弱引用,虚引用. 强引用: 只要引用存在,垃圾回收器永远不会回收Object obj = new Object();//可直接通过obj取得对应的对象 如obj.e ...

  5. 不可访问内存 Java四种引用包括强引用,软引用,弱引用,虚引用

    小结: 1.不可访问内存是指一组没有任何可访问指针指向的由计算机程序进行动态分配的内存块. 2.垃圾收集器能决定是否一个对象还是可访问的:任何被确定不可访问的对象将会被释放. https://zh.w ...

  6. java中的引用类型:强软弱虚

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

  7. ThreadLocal以及强软弱虚引用

    1.ThreadLocal ThreadLocal即线程本地,可以实现每个线程存入取出TreadLocal值互不影响.因为TheadLocal底层是用了一个Map结构存放数据,而这个Map是从当前这个 ...

  8. JAVA中的四种引用以及ReferenceQueue和WeakHashMap的使用示例

    简介: 本文主要介绍JAVA中的四种引用: StrongReference(强引用).SoftReferenc(软引用).WeakReferenc(弱引用).PhantomReference(虚引用) ...

  9. 【转载】Java的四种引用

    在Java中,虽然不需要程序员手动去管理对象的生命周期,但是如果希望某些对象具备一定的生命周期的话(比如内存不足时JVM就会自动回收某些对象从而避免OutOfMemory的错误)就需要用到软引用和弱引 ...

随机推荐

  1. ASP.NET Core 中间件 自定义全局异常中间件以及 MVC异常过滤器作用

    中间件是一种装配到应用管道以处理请求和响应的软件. 每个组件: 选择是否将请求传递到管道中的下一个组件. 可在管道中的下一个组件前后执行工作. 请求委托用于生成请求管道. 请求委托处理每个 HTTP ...

  2. 【kinetic】操作系统探索总结(六)使用smartcar进行仿真

    p { margin-bottom: 0.1in; direction: ltr; line-height: 120%; text-align: justify } a:link { color: r ...

  3. java时间的一些处理

    获取当前时间 System.currentTimeMillis() //第一种 Date date = new Date(); System.out.println(date.getTime()); ...

  4. codeforces 1438D,思路非常非常巧妙的构造题

    大家好,欢迎来到codeforces专题. 今天选择的问题是contest1438的D题,全场通过人数为1325人.一般在codeforces当中千人通过的题难度都不算太高,但是这题有点例外,虽然没有 ...

  5. CRM、DMP、CDP概念解析

    CRM.DMP.CDP,都是什么鬼?有什么区别差异?别说你都懂 摘自https://maxket.com/crm-dmp-cdp/ 如果您不想多花人生中宝贵的十分钟,那么不用多考虑了,上CDP吧.如果 ...

  6. JS中var与let的区别

    区别: var声明的变量,其作用域在该语句所在的函数之内,存在着变量提升的现象. let声明的变量,其作用域为该句所在的代码块内,不存在变量提升的问题. let相比于var,其不允许在相同作用域内,重 ...

  7. instanceof和isInstance的区别

    instanceof 是一个操作符(类似new, ==等) ( Object reference variable ) instanceof (class/interface type) if(a i ...

  8. SpringCloud --服务调用Feign

    介绍 服务间通信简介 一个系统可以由不同的微服务构成,比如一个电商系统可以由订单服务.商品服务.用户服务等共同组成. 这些服务相互独立,但又相互依赖.由于它们相互依赖,所以需要通过通信的方式来进行相互 ...

  9. [从源码学设计]蚂蚁金服SOFARegistry之续约和驱逐

    [从源码学设计]蚂蚁金服SOFARegistry之续约和驱逐 目录 [从源码学设计]蚂蚁金服SOFARegistry之续约和驱逐 0x00 摘要 0x01 业务范畴 1.1 失效剔除 1.2 服务续约 ...

  10. 【LeetCode】数组排序题 Array_Sorts

    数组排序 Array_Sorts LeetCode 数组排序题 88. 合并两个有序数组 合并两个有序数组 难度简单 给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nu ...