IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java的4种引用 -> 正文阅读

[Java知识库]Java的4种引用

????????Java中存在四种引用:StrongReference(强引用) 、SoftReferenc(软引用) 、WeakReferenc(弱引用)、PhantomReference(虚引用),虽然不常用,但是对于理解Java的回收等级还是很有帮助的,一句话来说这些引用只是不同回收等级的一种表现形式

StrongReference(强引用)

????????强引用是最经常使用的一种引用,如new操作创建的对象就属于强引用,如下代码,对于强引用要记住无论如何JVM都不会去回收其内存.

Object obj = new Object();

SoftReferenc(软引用)

????????软引用是由java.lang.ref.SoftReference所提供的功能,被其所关联的对象不存在强引用并且此时JVM内存不足才会去回收该对象, 个人不知道其用处,做缓存的话,现在的企业项目基本不是单体架构所以用处不大,倒是可以做内存警告,当对象被回收时则说明系统所需要的内存不足,那么就可以发邮件通知相关人员.

WeakReferenc(弱引用)

????????弱引用是java.lang.ref包下的WeakReferenc类所提供的包装功能,对于弱引用JVM会回收仅被弱引用所关联的对象。也就是说弱引用对象会在一次gc之后被回收,如下代码,其中obj1没被回收,因为其的引用是强引用,但是weakObj1与其关联是弱引用,因此不属于被收回对象.weakObj2所关联的new Object()只有一个弱引用关联,因此会被回收。

Object obj1 = new Object();
WeakReference<Object> weakObj1 = new WeakReference<Object>(obj1);
WeakReference<Object> weakObj2 = new WeakReference<Object>(new Object());
//主动回收
System.gc();

System.out.println(weakObj1.get()); // 非null
System.out.println(weakObj2.get()); // null

????????Java中提供了一个很棒的工具类WeakHashMap,按照注释所说,该类是一个键为弱引用类型的Map,与传统Map不同的是其键会自动删除释放掉,因为gc()时会自动释放,因此很适合做缓存这一类的需求

????????下面代码是Tomcat所实现的LRU(最少使用策略)缓存算法的实现,关键点在注释中给出。

import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;

public final class ConcurrentCache<K,V> {
    //LRU所允许的最大缓存量    
    private final int size;
    private final Map<K,V> eden;
    private final Map<K,V> longterm;
    
    public ConcurrentCache(int size) {
        this.size = size;
        //eden是主要缓存
        this.eden = new ConcurrentHashMap<>(size);
        //longterm是实现LRU算法的关键点.
        this.longterm = new WeakHashMap<>(size);
    }
    
    //get是先从eden中取出缓存,当不存在时则去longterm中获取缓存,并且此时获取到的缓存说明还在使用,因此会put到eden中(LRU算法)
    public V get(K k) {
        V v = this.eden.get(k);
        if (v == null) {
            synchronized (longterm) {
                v = this.longterm.get(k);
            }
            if (v != null) {
                this.eden.put(k, v);
            }
        }
        return v;
    }
    //put操作当size大于LRU最大容量时,则把缓存都放入到longterm,当this.eden.clear()后使其成为弱引用,那么LRU的实现则在get方法中体现了出来.
    public void put(K k, V v) {
        if (this.eden.size() >= size) {
            synchronized (longterm) {
                this.longterm.putAll(this.eden);
            }
            this.eden.clear();
        }
        this.eden.put(k, v);
    }
}

????????此方法如果操作时刚好遇到了一次gc,那么longterm的引用就会丢失,那么缓存就gg了.

PhantomReference(虚引用)

????????虚引用是由java.lang.ref.PhantomReference所提供的关联功能,虚引用对其原对象的生命周期毫无影响,其可以算是一种标记,当其所引用对象被回收时其会自动加入到引用队列中。也就是说你可以通过虚引用得到哪些对象已被回收。具体用法可以分析common.io中的org.apache.commons.io.FileCleaningTracker 该类中有一内部类class Tracker extends PhantomReference<Object>,也就是其包裹着虚引用对象,分析其构造函数,marker参数是该具体的虚引用,当marker被回收时,该对应的Track会被加入到引用队列queue中.

Tracker(String path, FileDeleteStrategy deleteStrategy, Object marker, ReferenceQueue<? super Object> queue) {
    //marker是具体的虚引用对象
    super(marker, queue);
    this.path = path;
    this.deleteStrategy = deleteStrategy == null ? FileDeleteStrategy.NORMAL : deleteStrategy;
}

????????文件删除则是该类维护的一个线程来进行的操作,既然对象回收后会加入到引用队列queue,那么该线程要做的功能自然是从引用队列中获取到对应的Track,然后执行其删除策略。在这个流程中虚引用起到的是跟踪所包裹对象作用,当包裹的的对象被回收时,这边会得到一个通知(将其加入到引用队列).

@Override
        public void run() {
            // thread exits when exitWhenFinished is true and there are no more tracked objects
            while (exitWhenFinished == false || trackers.size() > 0) {
                try {
                    // Wait for a tracker to remove.
                    Tracker tracker = (Tracker) q.remove(); // cannot return null
                    trackers.remove(tracker);
                    if (!tracker.delete()) {
                        deleteFailures.add(tracker.getPath());
                    }
                    tracker.clear();
                } catch (InterruptedException e) {
                    continue;
                }
            }
        }

Java学习视频

Java基础:

Java300集,Java必备优质视频_手把手图解学习Java,让学习成为一种享受

Java项目:

【Java游戏项目】1小时教你用Java语言做经典扫雷游戏_手把手教你开发游戏

【Java毕业设计】OA办公系统项目实战_OA员工管理系统项目_java开发

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-05-10 11:43:27  更:2022-05-10 11:44:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:33:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码