java 强软弱虚引用

在jdk1.2之后,java对引用的概念进行了扩充,将引用分为强引用(Strong Reference)软引用(Soft Reference)弱引用(Weak Reference)虚引用(Phantom Reference) 四种,这四种引用强度依次逐渐减弱。

对象层次的引用:

java.lang.Object
java.lang.ref.ReferenceQueue
java.lang.ref.Reference
java.lang.ref.SoftReference
java.lang.ref.WeakReference
java.lang.ref.PhantomReference

一、强引用

强引用就是指在程序代码之中普遍存在的,类似“Object o = new Object()”这类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象,即使发生OOM(OutOfMemoryError)
强引用是最普遍的引用:Object o = new Object();
如果要中断强引用和某个对象的关联,将对象的引用显示地设置为null,这样GC就会在合适的时候回收对象:
o = null; // 帮助垃圾收集器回收此引用所对应的对象
ArrayList的clear()实现源代码:

	/**
     * 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;
    }
 	@Test
    public void testStrong() {
        //通过引用链获取到对象,程序运行过程任意一个环节不会为null
        List<Integer> intList = new ArrayList<>();
        intList.add(new Integer("2"));
        Map<String, List<Integer>> map = new HashMap<>();
        map.put("aa", intList);
        System.out.println(map.get("aa").get(0));
    }

二、软引用

软引用用来描述一些还有用,但并非必需的对象。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。因此,这一点可以很好的用来解决OOM的问题,并且这个特性很适合用来实现缓存:如网页缓存、图片缓存等。在jdk1.2之后,提供了SoftReference类来实现软引用。

 	@Test
    public void testSoft1(){
        //创建一个软引用,包含一个对象
        SoftReference<Integer> soft = new SoftReference<>(new Integer("23456"));
        //软引用包含的对象可以通过get()获取到
        Integer num = soft.get();
    }

    @Test
    public void testSoft2(){
        //创建一个软引用,包含一个对象
        SoftReference<Integer> soft = new SoftReference<>(new Integer("23456"));
        //提醒系统进行一个垃圾收集
        System.gc();
        System.out.println(soft.get() == null); // false
    }

网页缓存实例:

package org.jgs1904.demo;

import java.lang.ref.SoftReference;

/**
 * @ClassName BrowserData
 * @Description 网页缓存模拟实现
 * @Author RenYuWen
 * @Since 2019/12/13 15:52
 */
public class BrowserData {

    public static void main(String[] args) {

        Browser prev = new Browser(); // 获取页面进行浏览
        SoftReference sr = new SoftReference(prev); // 浏览完毕后重置为软引用
        if(sr.get() != null){
            prev = (Browser) sr.get(); // 如果还没有被回收器回收,直接获取
        }else{
            prev = new Browser(); // 由于内存吃紧,所以对软引用的对象进行回收
            sr = new SoftReference(prev); // 重新构建
        }
    }

    static class Browser{}
    
}

图片缓存实例:

package org.jgs1904.demo;

import java.lang.ref.SoftReference;

/**
 * @ClassName Demo03
 * @Description 软引用
 * @Author RenYuWen
 * @Since 2019/12/12 18:38
 */
public class ImageData {

    private String path;
    private SoftReference<byte[]> dataRef; // 软引用

    public ImageData(String path){
        this.path = path;
        dataRef = new SoftReference<>(new byte[0]); 
    }
    
    // 读取图片数据并将数据返回
    private byte[] readImage(){ 
        return new byte[1024 * 1024]; // 省略读取文件的操作
    }

    // 获取图片数据
    public byte[] getData(){
        byte[] dataArray = dataRef.get(); // 从引用中获取文件数据
        if (dataArray == null || dataArray.length == 0){ // 如果为null
            dataArray = readImage(); // 重新获取图片数据
            dataRef = new SoftReference<>(dataArray); // 重新设置为软引用
        }
        return dataArray; // 如果不为null,直接返回,不需要再重新获取图片的数据
    }
}

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

三、弱引用

弱引用也是用来描述非必需对象的。但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收到被弱引用关联的对象。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

弱引用的作用在于解决强引用所带来的对象之间在存活时间上的耦合关系。弱引用最常见的用处是在集合类中,尤其在哈希表中。

哈希表的接口允许使用任何Java对象作为键来使用。当一个键值对被放入到哈希表中之后,哈希表对象本身就有了对这些键和值对象的引用。如果这种引用是强引用的话,那么只要哈希表对象本身还存活,其中所包含的键和值对象是不会被回收的。如果某个存活时间很长的哈希表中包含的键值对很多,最终就有可能消耗掉JVM中全部的内存。对于这种情况的解决办法就是使用弱引用来引用这些对象,这样哈希表中的键和值对象都能被垃圾回收。

在jdk1.2之后,提供了WeakReference类来实现弱引用。

 	@Test
    public void testWeak1(){
        //创建一个弱引用,包含一个对象
        WeakReference<Integer> weak = new WeakReference<>(new Integer("23456"));
        //弱引用包含的对象可以通过get()获取到
        Integer weakNum = weak.get();
    }

    @Test
    public void testWeak2(){
        //创建一个弱引用,包含一个对象
        WeakReference<Integer> weak = new WeakReference<>(new Integer("23456"));
        //提醒系统进行一次垃圾回收
        System.gc();
        System.out.println(weak.get() == null); // true
    }

四、虚引用

虚引用也称为幽灵引用或者幻影引用,它是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是希望能在这个对象被收集器回收时收到一个系统通知。在jdk1.2之后,提供了PhantomReference类来实现虚引用。

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

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

@Test
    public void testPhantom1(){
        //创建一个虚引用,包含一个对象
        ReferenceQueue<Integer> intRq = new ReferenceQueue<>();
        PhantomReference<Integer> phantom = new PhantomReference<>(new Integer("23456"),intRq);
        //弱引用包含的对象可以通过get()获取到
        Integer phantomNum = phantom.get();
    }

    @Test
    public void testPhantom2(){
        //创建一个虚引用,包含一个对象
        ReferenceQueue<Integer> intRq = new ReferenceQueue<>();
        PhantomReference<Integer> phantom = new PhantomReference<>(new Integer("23456"),intRq);
        Integer phantomNum = phantom.get();
        System.out.println(phantomNum == null); // true 虚引用获取不到包装的对象!虚引用用以调度回收前的清理工作!
    }

五、对比

引用类型GC回收时间用途生存时间
强引用never对象的一般状态JVM停止运行时
软引用内存不足时对象缓存内存不足时终止
弱引用GC工作时对象缓存GC后终止
虚引用unknownunknownunknown
深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值