JVM 中四种引用类型

简介: JVM 中四种引用类型

JVM 中四种引用类型


强引用


  • 只要存在强引用,垃圾收集器永远不会回收 例如:Object obj = new Object();


  • 帮助垃圾对象回收 obj = null, ArrayList 源码实现


/**
 * Removes all of the elements from this list.  The list will
 * be empty after this call returns.
 */
public void clear() {
    modCount++;
    // clear to let GC do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;
    size = 0;
} 


软引用


  • 用来描述一些还有用但并非必须的对象。对于软应用关联着的对象,在系统将要发生内存泄漏溢出(Full GC )之前, 将会把这些对象列进回收范围之中进行二次回收,如果这次回收还没有足够的内存,就会抛出OOM(内存溢出)异常。


  • 在JDK1.2 之后提供了SoftReference类来实现软引用, 这个特征非常适合在:网页缓存、图片缓存等。


  • 浏览器网页缓存实例


//获取页面进行浏览
Browser prev = new Browser();
//浏览完毕后置为软引用
SoftReference sr = new SoftReference();
if (sr.get() == null) {
    prev = rs.get();
} else {
    prev = new Browser();
    sr = new SoftReference(prev); 
}


  • 软引用可以和一个引用队列(ReferenceQueue) 联合使用,如果软引用的对象被垃圾回收器回收,虚拟机会把这个软引用加入到与之关联的引用队列中。


弱引用


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


  • JDK1.2之后,提供了WeakReference 类来实现弱引用


  • 示例:


import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.LinkedList;
public class ReferenceTest {
    private static ReferenceQueue<VeryBig> rq = new ReferenceQueue<>();
    public static void checkQueue() {
        Reference<? extends VeryBig> ref = null;
        while ((ref = rq.poll()) != null) {
            if (ref != null) {
                System.out.println("In queue:" + ((VeryBigWeakReference) (ref)).id);
            }
        }
    }
    public static void main(String[] args) {
        int size = 3;
        LinkedList<WeakReference<VeryBig>> weakList = new LinkedList<>();
        for (int i = 0; i < size; i++) {
            weakList.add(new VeryBigWeakReference(new VeryBig("Weak " + i), rq));
            System.out.println("Just created weak: " + weakList.getLast());
        }
        System.gc();
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        checkQueue();
    }
}
class VeryBig {
    public String id;
    /**
     * 占用空间,让线程进行回收
     */
    byte[] b = new byte[2 * 1024];
    public VeryBig(String id) {
        this.id = id;
    }
    @Override
    protected void finalize() {
        System.out.println("Finalizing VeryBig " + id);
    }
}
class VeryBigWeakReference extends WeakReference<VeryBig> {
    public String id;
    public VeryBigWeakReference(VeryBig big, ReferenceQueue<VeryBig> rq) {
        super(big, rq);
        this.id = big.id;
    }
    @Override
    protected void finalize() {
        System.out.println("Finalizing VeryBigWeakReference " + id);
    }
}


  • 输出结果


Just created weak: cn.edu.cqvie.gc.VeryBigWeakReference@5451c3a8
Just created weak: cn.edu.cqvie.gc.VeryBigWeakReference@2626b418
Just created weak: cn.edu.cqvie.gc.VeryBigWeakReference@5a07e868
Finalizing VeryBig Weak 2
Finalizing VeryBig Weak 1
Finalizing VeryBig Weak 0
In queue:Weak 0
In queue:Weak 1
In queue:Weak 2


虚引用


  • 虚引用称为幽灵引用或幻影引用。它是最弱的引用关系,一个独享是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来获取对象 实例。为一个对象设置虚应用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。在JDK1.2后,提供了PhantomReference 来实现虚引用。


四种引用的区别


四种引用的区别如下


引用类型 GC回收时间 用途 生存时间
强引用 never 对象的一般状态 JVM停止运行时
软引用 内存不足 对象缓存 内存足时终止
弱引用 GC时 对象缓存 GC后终止
虚引用 unknow unknow unknow



相关文章
|
存储 缓存 算法
JVM第三讲:深入理解java虚拟机之垃圾回收算法?CMS垃圾回收的基本流程?对象引用类型?
JVM第三讲:深入理解java虚拟机之垃圾回收算法?CMS垃圾回收的基本流程?对象引用类型?
556 0
|
Java
【JVM】深入理解Java引用类型:强引用、软引用、弱引用和虚引用
【JVM】深入理解Java引用类型:强引用、软引用、弱引用和虚引用
812 0
|
存储 缓存 算法
JVM 系列(5)吊打面试官:说一下 Java 的四种引用类型
JVM 系列(5)吊打面试官:说一下 Java 的四种引用类型
339 0
JVM 系列(5)吊打面试官:说一下 Java 的四种引用类型
|
Java Android开发
【Java 虚拟机原理】Java 引用类型 ( 强引用 | 软引用 | 弱引用 | 虚引用 | 静态变量 )
【Java 虚拟机原理】Java 引用类型 ( 强引用 | 软引用 | 弱引用 | 虚引用 | 静态变量 )
224 0
|
6月前
|
Arthas 存储 算法
深入理解JVM,包含字节码文件,内存结构,垃圾回收,类的声明周期,类加载器
JVM全称是Java Virtual Machine-Java虚拟机JVM作用:本质上是一个运行在计算机上的程序,职责是运行Java字节码文件,编译为机器码交由计算机运行类的生命周期概述:类的生命周期描述了一个类加载,使用,卸载的整个过类的生命周期阶段:类的声明周期主要分为五个阶段:加载->连接->初始化->使用->卸载,其中连接中分为三个小阶段验证->准备->解析类加载器的定义:JVM提供类加载器给Java程序去获取类和接口字节码数据类加载器的作用:类加载器接受字节码文件。
649 55
|
1月前
|
存储 缓存 Java
我们来说一说 JVM 的内存模型
我是小假 期待与你的下一次相遇 ~
211 4
|
1月前
|
存储 缓存 算法
深入理解JVM《JVM内存区域详解 - 世界的基石》
Java代码从编译到执行需经javac编译为.class字节码,再由JVM加载运行。JVM内存分为线程私有(程序计数器、虚拟机栈、本地方法栈)和线程共享(堆、方法区)区域,其中堆是GC主战场,方法区在JDK 8+演变为使用本地内存的元空间,直接内存则用于提升NIO性能,但可能引发OOM。
|
7月前
|
Arthas 监控 Java
Arthas memory(查看 JVM 内存信息)
Arthas memory(查看 JVM 内存信息)
623 6
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
2021 1