zoukankan      html  css  js  c++  java
  • JVM学习(五)对象的引用类型

    一、引言

      前面我们学习了JVM的垃圾回收机制,我们知道了垃圾回收是JVM的自发行为;虽然我们可以通过System.gc()Runtime.getRuntime().gc()进行显式调用垃圾回收 ,但JVM可以屏蔽掉显式的垃圾回收调用,且JVM也有自己的一套垃圾回收机制,那么我们有没有什么办法可以“告诉”JVM,哪些对象是可以使用以后回收,哪些对象保留呢?这里就要说一下JAVA对象的引用类型了。

    二、对象引用的简单介绍

    • 强引用:无论内存是否足够,不会回收。
    • 软引用:内存不足时,回收该引用关联的对象。
    • 弱引用:垃圾回收时,无论内存是否足够,都会回收。
    • 虚引用:任何时候都可能被垃圾回收器回收。

    Java中提供这四种引用类型主要有两个目的:

      • 1、让程序员通过代码的方式决定某些对象的生命周期
      • 2、第二是有利于JVM进行垃圾回收。

    三、对象引用代码示例

    强引用

      强引用是我们使用的最广泛,也是最普遍的一种引用类型,常见的创建对象的方式就使用的强引用:

    //1、强引用示例
    String str = new String();

    特点:

    • 只要某个对象是强引用的,或者有强引用与之关联,JVM必定不会回收这个对象
    • 内存不足的情况下,JVM会抛出OutOfMemory错误
    • 需要回收时,可以显式设置此对象为null,JVM就会自行在垃圾回收发生时去回收此对象

    软引用

      软引用是用来描述一些有用但并不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象:

    //2、软引用示例
    SoftReference<String> softStr = new SoftReference<String>(new String("这是一个软引用类型的字符串对象"));
    System.out.println(softStr.get());

      软引用相对与强引用来说,比较好的解决了OOM【Out Of Memory】的问题,可以把一些有用的数据,但又不是核心的内容通过软引用的形式来设置,那么当内存不足时就可以回收释放空间了。常见应用如软引用一个图片对象等。

    特点:

    • SoftReference类包裹引用
    • JVM内存不足时会回收【存在强引用关联时不回收】

    弱引用

      弱引用也是用来描述一些有用但并不是必需的对象,在Java中用java.lang.ref.WeakReference类来表示。对于弱引用关联着的对象,当JVM进行垃圾回收时,无论内存是否充足,都会回收:

    //3、弱引用示例
    WeakReference<String> weekStr = new WeakReference<String>(new String("这是一个弱引用类型的字符串对象"));
    System.out.println(weekStr.get());
    //显式调用JVM垃圾回收
    System.gc();
    //输出弱引用的内容【此时会输出null,因为在显式调用垃圾回收的时候,弱引用对象的内容已经被回收了】
    System.out.println(weekStr.get());

      PS:如果弱引用对象有对应的强引用关联,那么垃圾回收时是不会回收此弱引用的【软引用也类似】

    特点:

    • WeakReference类包裹引用
    • JVM无论内存充足与否会在垃圾回收时回收【存在强引用关联时不回收】

    虚引用

      虚引用不影响对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收

    //4、虚引用示例
    //4.1、创建一个引用队列【虚引用必须跟引用队列关联使用】
    ReferenceQueue<String> queue = new ReferenceQueue<String>();
    //4.2、创建一个虚引用包裹一个字符串对象的引用地址
    PhantomReference<String> phantomStr = new PhantomReference<String>(new String("这是一个虚引用类型的字符串对象"), queue);
    //4.3、输出引用内容【结果发现输出为null】
    System.out.println(phantomStr.get());

    特点:

    • PhantomReference类包裹引用
    • 任何时候都可能被垃圾回收器回收
    • 必须跟引用队列关联使用

    引用队列(ReferenceQueue)

    作用:

    • 用于监听Reference所指向的对象是否已经被垃圾回收

    使用场景:

    • 当大量使用各种引用(Reference)来包裹实例对象时,虽然引用(Reference)指向的对象可能被回收了,但Reference本身也是个对象,所以也需要回收,这时就需要使用ReferenceQueue了。

    回收模式上的区别:

    • SoftReferenceWeakReference的get()加入ReferenceQueue或get()返回null时,仅是表明其指示的对象已经进入垃圾回收流程,此时对象不一定已经被垃圾回收。
    • PhantomReference加入ReferenceQueue时,则表明对象需要且已被回收PS:所以虚引用的例子的4.3步骤,调用get方法时返回会为null】

     

  • 相关阅读:
    A basic Windows service in C++ (CppWindowsService)
    json转换为键值对辅助类
    函数参数复习
    python --------------网络(socket)编程
    计算器
    python------------------异常处理
    hashlib,configparser,logging模块
    面向对象之反射及内置方法
    python之--------封装
    继承进阶
  • 原文地址:https://www.cnblogs.com/riches/p/12707522.html
Copyright © 2011-2022 走看看