首页 > 其他分享 >强引用、软引用、弱引用、虚引用

强引用、软引用、弱引用、虚引用

时间:2023-04-12 21:33:47浏览次数:25  
标签:对象 Object 回收 引用 JVM new


强引用

强引用就是指在程序代码之中普遍存在的,比如下面这段代码中的object和str都是强引用:


Object object = new Object();


只要某个对象有强引用与之关联,JVM必定不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象。比如下面这段代码:

/**
 * 强引用示例
 *
 * @author tianwc
 * @date 2018-11-22
 */
public class StrongReferenceMain {
public static void main(String[] args) {
        StrongReferenceMain strongReferenceMain = new StrongReferenceMain();
        strongReferenceMain.test();
    }

public void test() {
        Object object = new Object();
        String str = "hello";
        Object[] objArr = new Object[1000];
    }
}

当运行至


Object[] objArr = new Object[1000];


这句时,如果内存不足,JVM会抛出OOM错误也不会回收object指向的对象。不过要注意的是,当test方法运行完之后,object和objArr都已经不存在了,所以它们指向的对象都会被JVM回收。

object和objArr是虚拟机栈-->栈帧上-->局部变量表-->reference

如果想中断强引用和某个对象之间的关联,可以显示地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象。

软引用

软引用是用来描述一些有用但并不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。因此,这一点可以很好地用来解决OOM的问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。

软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被JVM回收,这个软引用就会被加入到与之关联的引用队列中。下面是一个使用示例:

import java.lang.ref.SoftReference;
/**
 * 软引用示例
 *
 * @author tianwc
 * @date 2018-11-21
 */
public class SoftReferenceMain {
public static void main(String[] args) {
        SoftReference<String> sr = new SoftReference<>(new String("hello"));
        System.out.println(sr.get());
        //通知JVM的gc进行垃圾回收
        System.gc();
        System.out.println(sr.get());
    }
}

SoftReference代码

强引用、软引用、弱引用、虚引用_JVM

弱引用

弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。在java中,用java.lang.ref.WeakReference类来表示。下面是使用示例:

/**
 * 弱引用示例
 *
 * @author tianwc
 * @date 2018-11-21
 */
public class WeakReferenceMain {
public static void main(String[] args) {
        WeakReference<String> sr = new WeakReference<>(new String("hello"));

        System.out.println(sr.get());
        //通知JVM的gc进行垃圾回收
        System.gc();
        System.out.println(sr.get());
    }
}

在ThreadLocal中的使用场景

强引用、软引用、弱引用、虚引用_JVM_02

虚引用(PhantomReference)

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

要注意的是,虚引用必须和引用队列关联使用,当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会把这个虚引用加入到与之 关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

进一步理解软引用和弱引用

对于强引用,我们平时在编写代码时经常会用到。而对于其他三种类型的引用,使用得最多的就是软引用和弱引用,这2种既有相似之处又有区别。它们都是用来描述非必需对象的,但是被软引用关联的对象只有在内存不足时才会被回收,而被弱引用关联的对象在JVM进行垃圾回收时总会被回收。针对上面的特性,软引用适合用来进行缓存,当内存不够时能让JVM回收内存,弱引用能用来在回调函数中防止内存泄露。因为回调函数往往是匿名内部类,隐式保存有对外部类的引用,所以如果回调函数是在另一个线程里面被回调,而这时如果需要回收外部类,那么就会内存泄露,因为匿名内部类保存有对外部类的强引用。

                         老铁们帮忙点个赞

强引用、软引用、弱引用、虚引用_软引用_03


标签:对象,Object,回收,引用,JVM,new
From: https://blog.51cto.com/u_11702014/6186264

相关文章

  • c++指针参数传递和引用参数传递的区别
    1) 指针参数传递本质上是值传递,它所传递的是一个地址值。值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,会在栈中开辟内存空间以存放由主调函数传递进来的实参值,从而形成了实参的一个副本(替身)。值传递的特点是,被调函数对形式参数的任何操作都是作为局部变量进行的,......
  • Java到底是值传递还是引用传递?
    1.什么是形参和实参形参:就是形式参数,用于定义方法的时候使用的参数,是用来接收调用者传递的参数的。实参:就是实际参数,用于调用时传递给方法的参数。实参在传递给别的方法之前是要被预先赋值的。/***@author一灯*@apiNoteJava传递示例**/publicclassDemo{......
  • RUST——借用与引用
    引用与借用引用可以保证一个对象的引用作为参数而不是所有权fnmain(){lets1=String::from("hello");letlen=cal_len(&s1);println!("Thelengthof{}is{}",s1,len);}fncal_len(s:&String)->usize{//s.push_str(",world");无法通过......
  • C++核心编程之-引用
    引用引用的基本使用作用:给变量起别名语法:数据类型&别名=原名引用的注意事项引用必须初始化引用在初始化后,不可以改变示例:#include<iostream>usingnamespacestd;intmain(){ inta=30; intb=50; //int&c;//这行错误,引用必须初始化 int&c=a......
  • MordernC++之左值(引用)与右值(引用)
    左值与右值C++中左值与右值的概念是从C中继承而来,一种简单的定义是左值能够出现再表达式的左边或者右边,而右值只能出现在表达式的右边。inta=5; //a是左值,5是右值intb=a; //b是左值,a也是左值intc=a+b; //c是左值,a+b是右值另一种区分左值和右值的方法是:有......
  • C++逆向分析——引用
    引用类型引用类型就是变量的别名,其在初始化时必须要赋值。//基本类型intx=1;int&ref=x;ref=2;printf("%d\n",ref); //类Personp;Person&ref=p;ref.x=10;printf("%d\n",p.x); //指针类型int******x=(int******)1;int******&ref=x;r......
  • wpf CommunityToolkit.Mvvm8.1 MVVM工具包安装引用指南
    CommunityToolkit.Mvvm包(又名MVVM工具包,以前名为Microsoft.Toolkit.Mvvm)是一个现代、快速且模块化的MVVM库。它支持:.NETStandard2.0、.NETStandard2.1和.NET6(UIFramework不支持) 文档地址:https://learn.microsoft.com/zh-cn/dotnet/communitytoolkit/mvvm/......
  • 小程序自定义组件 - 创建与引用
    简单理解组件即"页面的一部分".组件化开发也更多是为了代码复用,方便管理和提高开发效率.前端的组件化开发我想大抵也是借鉴后端开发思想吧.从前端的实现来看,以vue为例即通过扩展自定义HTML标签的的形式,让其局部拥有"单文件"的功能(包括了模板,样式,逻辑).然后组......
  • java中的引用
    引用分类强引用强引用是我们常见的普通对象引用,只有还有强引用指向一个对象,就表明这个对象还“存活”,垃圾收集器不会碰这个对象当一个对象被强引用对象引用时,它就处于可达状态,它是不能被垃圾回收的,即使出现了OOM也不会对该对象回收软引用软引用是相对于强引用......
  • 《渗透测试》安全开发-PHP应用&留言板功能&超全局变量&数据库操作&第三方插件引用 202
    PHPStorm:专业PHP开发IDEPhpStudy:ApacheMYSQL环境NavicatPremium:全能数据库管理工具 #数据导入-mysql架构&库表列1、数据库名,数据库表名,数据库列名2、数据库数据,格式类型,长度,键等 #数据库操作-mysqli函数&增删改查PHP函数:连接,选择,执行,结果,关闭等参考:https://......