关于Java的软引用及弱引用

简介: 概念介绍   1   Reference      描述一个对象的引用。其内部维持一个queue引用,用于跟踪对象的回收情况,当对象被回收时将当前reference引用入队   2   SoftReference      软引用,仅当JVM内存紧张时会回收关联对象,即JVM在抛出OOM异常之前会回收所有的SoftReference关联的对象。

概念介绍

 
1   Reference
     描述一个对象的引用。其内部维持一个queue引用,用于跟踪对象的回收情况,当对象被回收时将当前reference引用入队
 
2   SoftReference
     软引用,仅当JVM内存紧张时会回收关联对象,即JVM在抛出OOM异常之前会回收所有的SoftReference关联的对象。
     在对象被回收之后的某个时间点(立即或延迟)进行入队操作
 
3   WeakReference
     弱引用,当JVM执行垃圾回收时(如System.gc触发)回收其关联对象。
     在对象被回收之后的某个时间点(立即或延迟)进行入队操作
 
4   PhantomReference
     虚引用,实现了延迟可控、可再生(重复使用对象)的回收机制。
     当JVM第一次垃圾回收时并不回收关联对象,而是直接将refercence对象入队;
     当reference对象操作出队(poll)时,其内部Queue对象被置换为一个特殊的NULL队列(不允许入队);
     于是当JVM第二次垃圾回收时尝试将其入队发现失败,于是JVM才将关联对象回收。
     为了保护虚引用对象可再生,该reference的get方法总是返回null。
 

代码示例

package reference;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;

public class ReferenceTest {

    public static void main(String[] args) {
        System.out.println("弱引用==============");
        testWeakReference();

        System.out.println("软引用==============");

        testSoftReference();

        System.out.println("虚引用==============");
        testPhantomReference();
    }

    /**
     * 测试弱引用
     */
    private static void testWeakReference() {
        Object obj = new Object();

        // 构建弱引用
        ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
        WeakReference<Object> weakRef = new WeakReference<Object>(obj, refQueue);

        // 关联对象
        System.out.println(weakRef.get());
        // 检查入队情况
        System.out.println(refQueue.poll());
        obj = null;
        System.gc();

        // 延迟,等待入队操作执行
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // 关联对象是否回收
        System.out.println(weakRef.get());
        // 是否入队
        System.out.println(refQueue.poll());
    }

    /**
     * 测试软引用
     */
    private static void testSoftReference() {
        Object obj = new Object();
        ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
        SoftReference<Object> weakRef = new SoftReference<Object>(obj, refQueue);
        // 关联对象
        System.out.println(weakRef.get());
        // 检查入队情况
        System.out.println(refQueue.poll());
        obj = null;
        System.gc();

        // 延迟,等待入队操作执行
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // 关联对象是否回收
        System.out.println(weakRef.get());
        // 是否入队
        System.out.println(refQueue.poll());
    }

    /**
     * 测试虚引用
     */
    private static void testPhantomReference() {
        Object obj = new Object();
        ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
        PhantomReference<Object> weakRef = new PhantomReference<Object>(obj, refQueue);
        // 关联对象
        System.out.println(weakRef.get());
        // 检查入队情况
        System.out.println(refQueue.poll());
        obj = null;
        System.gc();

        // 延迟,等待入队操作执行
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // 关联对象是否回收
        System.out.println(weakRef.get());
        // 是否入队
        System.out.println(refQueue.poll());

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println("Phantom Reference's referent recycled.");
    }
}

  

 
输出
弱引用==============
java.lang.Object@1fb8ee3
null
null
java.lang.ref.WeakReference@14318bb
软引用==============
java.lang.Object@ca0b6
null
java.lang.Object@ca0b6
null
虚引用==============
null
null
null
java.lang.ref.PhantomReference@1b67f74
Phantom Reference's referent recycled.
 

相关博文

 
img_9b09a36f6de95886f52ce82fa1e89c88.jpe

作者: zale

出处: http://www.cnblogs.com/littleatp/, 如果喜欢我的文章,请关注我的公众号

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出 原文链接  如有问题, 可留言咨询.

目录
打赏
0
0
0
0
929
分享
相关文章
Java面试题:解释强引用、软引用、弱引用和虚引用在Java中是如何工作的?
Java面试题:解释强引用、软引用、弱引用和虚引用在Java中是如何工作的?
54 1
java面试题目 强引用、软引用、弱引用、幻象引用有什么区别?具体使用场景是什么?
【6月更文挑战第28天】在 Java 中,理解和正确使用各种引用类型(强引用、软引用、弱引用、幻象引用)对有效的内存管理和垃圾回收至关重要。下面我们详细解读这些引用类型的区别及其具体使用场景。
115 3
|
8月前
|
开发与运维引用问题之软引用又在Java特点如何解决
开发与运维引用问题之软引用又在Java特点如何解决
59 0
Java 中的强引用、弱引用、软引用和虚引用
引用方式内存不足时垃圾回收机制启动时其余情况强引用否否否软引用是否否弱引用是是否虚引用可能可能可能在一般的程序中,弱引用和虚引用很少会被用到,强引用天天都在用就不必我说了,在有些情况下(如资源文件很大,但并不是全部要在同一时刻使用)我们会使用软引用来代替原来的强引用,一是可以避免某些情况下产生的 OOM,此外,它可以减少程序使用的内存,加速程序的运行。
110 1
|
10月前
|
【JAVA】强引用、软引用、弱引用、幻象引用有什么区别?
幻象引用:幻象引用是最弱的引用类型,几乎不影响对象的生命周期。它们主要用于在对象被回收前进行某些预处理操作,例如在对象被销毁时执行特定的清理任务。
77 0
|
10月前
|
【JVM】深入理解Java引用类型:强引用、软引用、弱引用和虚引用
【JVM】深入理解Java引用类型:强引用、软引用、弱引用和虚引用
575 0
Java垃圾回收: 什么是强引用、软引用、弱引用和虚引用?
Java垃圾回收: 什么是强引用、软引用、弱引用和虚引用?
94 2
Java内存泄漏知识(软引用、弱引用等)
要学习内存泄漏,我们要知道一些基础知识,如Java引用分类:
|
8天前
|
【Java并发】【线程池】带你从0-1入门线程池
欢迎来到我的技术博客!我是一名热爱编程的开发者,梦想是编写高端CRUD应用。2025年我正在沉淀中,博客更新速度加快,期待与你一起成长。 线程池是一种复用线程资源的机制,通过预先创建一定数量的线程并管理其生命周期,避免频繁创建/销毁线程带来的性能开销。它解决了线程创建成本高、资源耗尽风险、响应速度慢和任务执行缺乏管理等问题。
117 60
【Java并发】【线程池】带你从0-1入门线程池
|
4天前
|
【源码】【Java并发】【线程池】邀请您从0-1阅读ThreadPoolExecutor源码
当我们创建一个`ThreadPoolExecutor`的时候,你是否会好奇🤔,它到底发生了什么?比如:我传的拒绝策略、线程工厂是啥时候被使用的? 核心线程数是个啥?最大线程数和它又有什么关系?线程池,它是怎么调度,我们传入的线程?...不要着急,小手手点上关注、点赞、收藏。主播马上从源码的角度带你们探索神秘线程池的世界...
40 0
【源码】【Java并发】【线程池】邀请您从0-1阅读ThreadPoolExecutor源码

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等