Java四大引用

目录

Java四大引用:强引用、弱引用、软引用、虚引用

强引用

软引用

弱引用

弱引用的应用

WeakHashMap

ThreadLocal

虚引用

Java引用总结


Java四大引用:强引用、弱引用、软引用、虚引用

对象的引用使程序能更加灵活地控制对象的生命周期,4种级别由高到低依次为:强引用、软引用、弱引用和虚引用。

 

 

强引用

强引用是最普遍的引用,一般把一个对象赋给一个引用变量,这个引用变量就是强引用。

//  强引用
Student s = new Student();

回收时机:从来不会

用途:对象的一般状态

生存时间:JVM 停止运行时终止

如果一个对象具有强引用,垃圾回收器不会回收该对象,当内存空间不足时,JVM 宁愿抛出 OutOfMemoryError异常。

如果强引用对象不使用时,需要弱化从而使GC能够回收,如下:

//帮助垃圾收集器回收此对象
Student = null;

显式地设置 Student 对象为null,或让其超出对象的生命周期范围,则GC认为该对象不存在引用,这时就可以回收这个对象,具体什么时候收集这要取决于GC算法。

举例:

package com.Guocheng.java.refenence;

/**
* 强引用举例
*
* @author Guocheng
*/
public class StrongRefenenceDemo {

    public static void main(String[] args) {
        Object o1 = new Object();
        Object o2 = o1;
        o1 = null;
        System.gc();
        System.out.println(o1);  //null
        System.out.println(o2);  //java.lang.Object@2503dbd3
    }
}

StrongRefenenceDemo 中尽管 o1已经被回收,但是 o2 强引用 o1,一直存在,所以不会被GC回收。

软引用

软引用是一种相对强引用弱化了一些的引用,需要用java.lang.ref.SoftReference 类来实现。

比如:

String str=new String("abc");                                     // 强引用
SoftReference<String> softRef=new SoftReference<String>(str);     // 软引用

如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。

先通过一个例子来了解一下软引用:

/**
* 弱引用举例
*
* @author Guocheng
*/
Object obj = new Object();
SoftReference softRef = new SoftReference<Object>(obj);//删除强引用
obj = null;//调用gc

// 对象依然存在
System.gc();System.out.println("gc之后的值:" + softRef.get());

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

ReferenceQueue<Object> queue = new ReferenceQueue<>();
Object obj = new Object();
SoftReference softRef = new SoftReference<Object>(obj,queue);//删除强引用
obj = null;//调用gc
System.gc();
System.out.println("gc之后的值: " + softRef.get()); // 对象依然存在
//申请较大内存使内存空间使用率达到阈值,强迫gc
byte[] bytes = new byte[100 * 1024 * 1024];//如果obj被回收,则软引用会进入引用队列
Reference<?> reference = queue.remove();if (reference != null){
    System.out.println("对象已被回收: "+ reference.get());  // 对象为null
}

软引用通常用在对内存敏感的程序中,比如高速缓存就有用到软引用,内存够用的时候就保留,不够用就回收。

我们看下 Mybatis 缓存类 SoftCache 用到的软引用:

public Object getObject(Object key) {
    Object result = null;
    SoftReference<Object> softReference = (SoftReference)this.delegate.getObject(key);
    if (softReference != null) {
        result = softReference.get();
        if (result == null) {
            this.delegate.removeObject(key);
        } else {
            synchronized(this.hardLinksToAvoidGarbageCollection) {
                this.hardLinksToAvoidGarbageCollection.addFirst(result);
                if (this.hardLinksToAvoidGarbageCollection.size() > this.numberOfHardLinks) {
                    this.hardLinksToAvoidGarbageCollection.removeLast();
                }
            }
        }
    }
    return result;}

注意:软引用对象是在 JVM 内存不够的时候才会被回收,我们调用System.gc()方法只是起通知作用,JVM什么时候扫描回收对象是JVM自己的状态决定的,就算扫描到软引用对象也不一定会回收它,只有内存不够的时候才会回收。

弱引用

弱引用的使用和软引用类似,只是关键字变成了 WeakReference:

Student s = new Student();
WeakReference<Student> wr = new WeakReference<Student>(s);

弱引用的特点是不管内存是否足够,只要发生 GC,都会被回收。

举例说明:

public class WeakHashMapDemo {

    public static void main(String[] args) throws InterruptedException {
        myHashMap();
        myWeakHashMap();
    }

    public static void myHashMap() {
        HashMap<String, String> map = new HashMap<String, String>();
        String key = new String("k1");
        String value = "v1";
        map.put(key, value);
        System.out.println(map);

        key = null;
        System.gc();

        System.out.println(map);
    }

    public static void myWeakHashMap() throws InterruptedException {
        WeakHashMap<String, String> map = new WeakHashMap<String, String>();
        //String key = "weak";
        // 刚开始写成了上边的代码
        //思考一下,写成上边那样会怎么样? 那可不是引用了
        String key = new String("weak");
        String value = "map";
        map.put(key, value);
        System.out.println(map);
        //去掉强引用
        key = null;
        System.gc();
        Thread.sleep(1000);
        System.out.println(map);
    }}

弱引用的应用

WeakHashMap

public class WeakHashMapDemo {

    public static void main(String[] args) throws InterruptedException {
        myHashMap();
        myWeakHashMap();
    }

    public static void myHashMap() {
        HashMap<String, String> map = new HashMap<String, String>();
        String key = new String("k1");
        String value = "v1";
        map.put(key, value);
        System.out.println(map);

        key = null;
        System.gc();

        System.out.println(map);
    }

    public static void myWeakHashMap() throws InterruptedException {
        WeakHashMap<String, String> map = new WeakHashMap<String, String>();
        //String key = "weak";
        // 刚开始写成了上边的代码
        //思考一下,写成上边那样会怎么样? 那可不是引用了
        String key = new String("weak");
        String value = "map";
        map.put(key, value);
        System.out.println(map);
        //去掉强引用
        key = null;
        System.gc();
        Thread.sleep(1000);
        System.out.println(map);
    }}

当key只有弱引用时,GC发现后会自动清理键和值,作为简单的缓存表解决方案。

ThreadLocal

static class ThreadLocalMap {

    static class Entry extends WeakReference<ThreadLocal<?>> {
        Object value;

        Entry(ThreadLocal<?> k, Object v) {
            super(k);
            value = v;
        }
    }
    //......}

ThreadLocal.ThreadLocalMap.Entry 继承了弱引用,key为当前线程实例,和WeakHashMap基本相同。

虚引用

虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。

虚引用也称为“幽灵引用”或者“幻影引用”,它是最弱的一种引用关系。

虚引用需要java.lang.ref.PhantomReference 来实现:

A a = new A();
ReferenceQueue<A> rq = new ReferenceQueue<A>();
PhantomReference<A> prA = new PhantomReference<A>(a, rq);

虚引用主要用来跟踪对象被垃圾回收器回收的活动。

虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue)联合使用,当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。

Java引用总结

java4种引用的级别由高到低依次为:强引用 > 软引用 > 弱引用 > 虚引用。

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Java 有四种不同类型的引用: 1. 强引用(Strong Reference):通常使用的引用方式,使用强引用的对象在内存空间不足时不会被回收。 2. 软引用(Soft Reference):当内存空间不足时,对象可能会被回收,但是在回收之前它可以被缓存。 3. 弱引用(Weak Reference):当内存空间不足时,对象很快就会被回收。 4. 虚引用(Phantom Reference):它不能单独使用,必须和引用队列(ReferenceQueue)一起使用,当对象被回收时,JVM会把它加入到引用队列中。 这四种引用的不同在于,它们对垃圾回收器的回收策略不同,因此它们对于内存管理的影响不同。 ### 回答2: Java四大引用分别是强引用、软引用、弱引用和虚引用。 1. 强引用Java中最常见的引用类型。通过 `new` 关键字生成的对象默认都是强引用。强引用的对象不会被垃圾回收器回收,即使内存不足时也不会被回收。只有当强引用失去引用时,垃圾回收器才会将其回收。 2. 软引用Java中的软引用是用来描述一些还有用但不是必需的对象。在内存不足时,垃圾回收器会选择性地回收软引用对象。这种引用常常用于缓存数据,当内存足够时,可以提供数据的快速访问,当内存不足时,可以被回收释放内存。 3. 弱引用Java中的弱引用是比软引用更弱一些的引用类型。弱引用对象在垃圾回收时,只要被垃圾回收器发现,就会被回收。弱引用通常用于跟踪对象的状态,当对象被回收时,可以执行特定的操作。 4. 虚引用Java中的虚引用是最弱的一种引用。虚引用主要用于对象回收跟踪。与弱引用不同的是,虚引用在任何时候都可能被垃圾回收器回收,甚至无法通过虚引用获取对象。虚引用一般与引用队列(Reference Queue)联合使用,用于监控对象被垃圾回收的状态。 引用的不同类型在内存管理中起到不同的作用,能够提供更灵活的内存控制机制。程序员可以根据对象的生命周期和内存需求,选择合适的引用类型,从而更好地管理内存。 ### 回答3: Java四大引用是强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)。 1. 强引用是默认的引用类型,也是最常用的引用类型。当对象被一个强引用引用时,对象将会一直存在,不会被垃圾回收器回收。 2. 软引用用来描述一些还有用但并非必须的对象。当内存不足时,垃圾回收器可能会回收软引用对象所占用的内存。可以通过SoftReference类来创建软引用。 3. 弱引用用来描述非必须的对象,它的生命周期比软引用更短。当垃圾回收器执行垃圾回收时,无论内存是否足够,都会回收弱引用对象。可以通过WeakReference类来创建弱引用。 4. 虚引用是最弱的引用类型,几乎没有实质性的作用。用来跟踪对象被垃圾回收器回收的活动。无法通过虚引用获得对象的实例,其主要作用是在对象被回收前收到一个系统通知。可以通过PhantomReference类来创建虚引用。 在Java中,使用合适的引用类型可以更好地管理内存,避免内存溢出。强引用应该谨慎使用,避免产生内存泄漏。而软引用和弱引用则可以用来优化缓存机制,当内存紧张时自动释放缓存。虚引用则主要用于追踪对象的回收情况。理解并正确使用这四大引用可以提高代码的性能和健壮性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

雾里有果橙

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

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

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

打赏作者

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

抵扣说明:

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

余额充值