JVM之引用类型

前序:

每一种编程语言都有自己操作内存中元素的方式,例如在 C 和 C++ 里是通过指针,而在 java 中则是通过“引用”。在 JDK.1.2 之后,Java 对引用的概念进行了扩充,将引用分为了:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)4 种,这 4 种引用的强度依次减弱

一、强引用

new 对象,构造方法引用对象就是强引用

当JVM内存空间不足,JVM宁愿抛出OutOfMemoryError运行时错误(OOM),使程序异常终止,也不会靠随意回收具有强引用的“存活”对象来解决内存不足的问题。对于一个普通的对象,如果没有其他的引用关系,只要超过了引用的作用域或者显式地将相应(强)引用赋值为 null,就是可以被垃圾收集的了,具体回收时机还是要看垃圾收集策略

Object object = new Object(),当给Object object=null时,强引用解除,此时new Object对象才能被回收

例如:String str = "abc";

List<String> list = new Arraylist<String>();

list.add(str);

举个栗子:

package com.feixiang.platform.stu.jvm.reference.strong;

/**
 * Created with IntelliJ IDEA.
 * Description: 强引用测试类
 *
 * @PackageName com.feixiang.platform.stu.jvm.reference.strong
 * @Author: ldwtxwhspring
 * @Date: 2023-11-29 下午8:04
 * @Version: 1.0.0
 */
public class StrongReference {
    public static String getUserName(User user){
        if (null==user){
            System.out.println("被收集");
            return null;
        }
        System.out.println("获取到---》"+user.getName());
        return user.getName();
    }

    public static void main(String[] args) {
        User user = new User();
        user.setName("张三丰");
        getUserName(user);
        user = null;
        System.gc(); //显示调用GC不一定会被回收,可以多尝试几次,可以修改xms,xmx值让jvm主动去收集
        getUserName(user);
    }
}

实体类如下:

 

package com.feixiang.platform.stu.jvm.reference.strong;

/**
 * Created with IntelliJ IDEA.
 * Description: 实体类
 *
 * @PackageName com.feixiang.platform.stu.jvm.reference.strong
 * @Author: ldwtxwhspring
 * @Date: 2023-11-29 下午8:04
 * @Version: 1.0.0
 */
public class User {
    public Integer id;
    public String name;
    public String mobile;
    public String address;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id=id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name=name;
    }

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile=mobile;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address=address;
    }
}

二、软引用

如果一个对象只具有软引用,那就类似于可有可物的生活用品。如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存

软引用在实际中有重要的应用,例如浏览器的后退按钮

举个栗子:

package com.feixiang.platform.stu.jvm.reference.softreference;

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

/**
 * Created with IntelliJ IDEA.
 * Description: 软引用测试类
 *
 * @PackageName com.feixiang.platform.stu.jvm.reference.softreference
 * @Author: ldwtxwhspring
 * @Date: 2023-11-29 下午7:54
 * @Version: 1.0.0
 */
public class SoftReferenceTest {
    public static void soft() throws Exception{
        Object obj = new Object();
        ReferenceQueue rq = new ReferenceQueue<>();
        SoftReference sr = new SoftReference(obj, rq);		//创建关于obj的软引用,使用引用队列
        System.out.println(sr.get());						//get方法会输出这个obj对象的hashcode
        System.out.println(rq.poll());						//输出为null
        obj = null;
        System.gc();
        Thread.sleep(200);								//因为finalizer线程优先级很低,所以让线程等待200ms
        System.out.println(sr.get());						//因为堆空间没满,可有可无的特性,所以还是会输出这个obj对象的hashcode

        System.out.println(rq.poll());						//自然队列为null
    }


    public static void main(String[] args) {
        try {
            soft();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

三、弱引用

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

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

弱引用在我们的开发中也很常见:最典型的就是大家熟知的:ThreadLocal,WeakHashMap,有兴趣的可以自行研究源码啦

上个栗子吧:

package com.feixiang.platform.stu.jvm.reference.weak;

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

/**
 * Created with IntelliJ IDEA.
 * Description: 弱引用测试类
 *
 * @PackageName com.feixiang.platform.stu.jvm.reference.weak
 * @Author: ldwtxwhspring
 * @Date: 2023-11-29 下午7:58
 * @Version: 1.0.0
 */
public class WeakReferenceTest {
    public static void weak() throws Exception{
        Object obj = new Object();
        ReferenceQueue rq = new ReferenceQueue<>();
        WeakReference wr = new WeakReference(obj,rq);
        System.out.println(wr.get());
        System.out.println(rq.poll());
        obj = null;
        System.gc();
        Thread.sleep(200);
        System.out.println(wr.get());			//这时候会输出null
        System.out.println(rq.poll());			//rq队列里也会存放这个弱引用,输出它的hashcode
    }

    public static void main(String[] args) {
        try {
            weak();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

四、虚引用

虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。虚引用主要用来跟踪对象被垃圾回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用

总结:

在实际程序设计中一般很少使用弱引用与虚引用,使用软用的情况较多,这是因为软引用可以加速JVM对垃圾内存的回收速度,可以维护系统的运行安全,防止内存溢出(OutOfMemory)等问题的产生,学好引用类型也是高效编程的基础哦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ldwtxwh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值