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



相关文章
|
12月前
|
存储 缓存 算法
JVM第三讲:深入理解java虚拟机之垃圾回收算法?CMS垃圾回收的基本流程?对象引用类型?
JVM第三讲:深入理解java虚拟机之垃圾回收算法?CMS垃圾回收的基本流程?对象引用类型?
203 0
|
5月前
|
Java
【JVM】深入理解Java引用类型:强引用、软引用、弱引用和虚引用
【JVM】深入理解Java引用类型:强引用、软引用、弱引用和虚引用
483 0
|
存储 缓存 算法
JVM 系列(5)吊打面试官:说一下 Java 的四种引用类型
JVM 系列(5)吊打面试官:说一下 Java 的四种引用类型
200 0
JVM 系列(5)吊打面试官:说一下 Java 的四种引用类型
|
Java Android开发
【Java 虚拟机原理】Java 引用类型 ( 强引用 | 软引用 | 弱引用 | 虚引用 | 静态变量 )
【Java 虚拟机原理】Java 引用类型 ( 强引用 | 软引用 | 弱引用 | 虚引用 | 静态变量 )
150 0
|
2月前
|
Java Docker 索引
记录一次索引未建立、继而引发一系列的问题、包含索引创建失败、虚拟机中JVM虚拟机内存满的情况
这篇文章记录了作者在分布式微服务项目中遇到的一系列问题,起因是商品服务检索接口测试失败,原因是Elasticsearch索引未找到。文章详细描述了解决过程中遇到的几个关键问题:分词器的安装、Elasticsearch内存溢出的处理,以及最终成功创建`gulimall_product`索引的步骤。作者还分享了使用Postman测试接口的经历,并强调了问题解决过程中遇到的挑战和所花费的时间。
|
11天前
|
存储 算法 Java
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
本文介绍了 JVM 的内存区域划分、类加载过程及垃圾回收机制。内存区域包括程序计数器、堆、栈和元数据区,每个区域存储不同类型的数据。类加载过程涉及加载、验证、准备、解析和初始化五个步骤。垃圾回收机制主要在堆内存进行,通过可达性分析识别垃圾对象,并采用标记-清除、复制和标记-整理等算法进行回收。此外,还介绍了 CMS 和 G1 等垃圾回收器的特点。
46 0
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
|
2月前
|
存储 算法 Oracle
不好意思!耽误你的十分钟,JVM内存布局还给你
先赞后看,南哥助你Java进阶一大半在2006年加州旧金山的JavaOne大会上,一个由顶级Java开发者组成的周年性研讨会,公司突然宣布将开放Java的源代码。于是,下一年顶级项目OpenJDK诞生。Java生态发展被打开了新的大门,Java 7的G1垃圾回收器、Java 8的Lambda表达式和流API…大家好,我是南哥。一个Java学习与进阶的领路人,相信对你通关面试、拿下Offer进入心心念念的公司有所帮助。
不好意思!耽误你的十分钟,JVM内存布局还给你
|
2月前
|
存储 算法 Java
JVM自动内存管理之垃圾收集算法
文章概述了JVM内存管理和垃圾收集的基本概念,提供一个关于JVM内存管理和垃圾收集的基础理解框架。
JVM自动内存管理之垃圾收集算法
|
2月前
|
存储 Java 程序员
JVM自动内存管理之运行时内存区
这篇文章详细解释了JVM运行时数据区的各个组成部分及其作用,有助于理解Java程序运行时的内存布局和管理机制。
JVM自动内存管理之运行时内存区