java的WeakHashMap可以用来做缓存使用?强软弱虚四种引用对比
在 Java 中,引用(Reference)机制用于管理对象的生命周期和垃圾回收。Java 提供了四种类型的引用:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)。WeakHashMap 使用弱引用来存储键,从而在键不再被强引用引用时自动移除对应的条目。下面是 WeakHashMap 的使用方法以及四种引用的优缺点对比。
WeakHashMap 使用方法
基本概念
- 弱引用(Weak Reference):弱引用不会阻止对象被垃圾回收。如果一个对象只被弱引用引用,并且没有其他强引用引用它,那么该对象在下一次垃圾回收时会被回收。
- 自动移除:当
WeakHashMap中的键被垃圾回收时,对应的键值对会自动从WeakHashMap中移除。
主要方法
WeakHashMap 实现了 Map 接口,因此它提供了 Map 接口中的所有方法,如 put, get, remove, containsKey, containsValue, size, isEmpty, clear 等。
示例代码
以下是一些常见的 WeakHashMap 使用示例:
1. 基本用法
import java.util.Map;
import java.util.WeakHashMap;public class WeakHashMapExample {public static void main(String[] args) {Map<Key, String> weakMap = new WeakHashMap<>();Key key1 = new Key("key1");Key key2 = new Key("key2");weakMap.put(key1, "Value1");weakMap.put(key2, "Value2");System.out.println("Initial WeakHashMap: " + weakMap);// 清除强引用key1 = null;key2 = null;// 强制进行垃圾回收System.gc();// 等待一段时间,确保垃圾回收完成try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("WeakHashMap after GC: " + weakMap);}static class Key {private String id;public Key(String id) {this.id = id;}@Overridepublic String toString() {return "Key{" + "id='" + id + "'}";}@Overridepublic int hashCode() {return id.hashCode();}@Overridepublic boolean equals(Object obj) {if (this == obj) return true;if (obj == null || getClass() != obj.getClass()) return false;Key key = (Key) obj;return id.equals(key.id);}}
}
输出:
Initial WeakHashMap: {Key{id='key1'}=Value1, Key{id='key2'}=Value2}
WeakHashMap after GC: {}
解释:
- 创建了一个
WeakHashMap并添加了两个键值对。 - 清除了对键的强引用。
- 强制进行垃圾回收,并等待一段时间。
- 垃圾回收后,
WeakHashMap中的所有条目都被移除,因为键不再被强引用引用。
2. 使用弱引用的缓存
import java.util.Map;
import java.util.WeakHashMap;public class WeakHashMapCacheExample {public static void main(String[] args) {Map<Key, String> cache = new WeakHashMap<>();Key key1 = new Key("key1");Key key2 = new Key("key2");cache.put(key1, "Value1");cache.put(key2, "Value2");System.out.println("Initial Cache: " + cache);// 清除对 key1 的强引用key1 = null;// 强制进行垃圾回收System.gc();// 等待一段时间,确保垃圾回收完成try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Cache after GC: " + cache);// 重新获取 key2 的值System.out.println("Value for key2: " + cache.get(key2));}static class Key {private String id;public Key(String id) {this.id = id;}@Overridepublic String toString() {return "Key{" + "id='" + id + "'}";}@Overridepublic int hashCode() {return id.hashCode();}@Overridepublic boolean equals(Object obj) {if (this == obj) return true;if (obj == null || getClass() != obj.getClass()) return false;Key key = (Key) obj;return id.equals(key.id);}}
}
输出:
Initial Cache: {Key{id='key1'}=Value1, Key{id='key2'}=Value2}
Cache after GC: {Key{id='key2'}=Value2}
Value for key2: Value2
解释:
- 创建了一个
WeakHashMap作为缓存,并添加了两个键值对。 - 清除了对
key1的强引用。 - 强制进行垃圾回收,并等待一段时间。
- 垃圾回收后,
key1对应的条目被移除,而key2对应的条目仍然存在。 - 重新获取
key2的值,验证缓存中仍然存在该条目。
强引用、软引用、弱引用和虚引用的对比
强引用(Strong Reference)
- 定义:强引用是最常见的引用类型,只要对象有强引用,垃圾回收器就不会回收该对象。
- 使用场景:大多数对象使用强引用。
- 优点:
- 对象不会被垃圾回收,确保对象的生命周期。
- 缺点:
- 容易导致内存泄漏,因为对象不会被自动回收。
软引用(Soft Reference)
- 定义:软引用不会阻止对象被垃圾回收,但只有在内存不足时才会被回收。
- 使用场景:适用于实现内存敏感的缓存。
- 优点:
- 在内存不足时可以回收对象,避免内存溢出。
- 缺点:
- 对象的回收时间不可预测,可能导致缓存中的数据丢失。
- 需要额外的管理来处理软引用。
弱引用(Weak Reference)
- 定义:弱引用不会阻止对象被垃圾回收,只要对象没有其他强引用引用它,就会被回收。
- 使用场景:适用于实现缓存,避免内存泄漏。
- 优点:
- 对象的回收时间可预测,只要没有强引用引用对象,就会被回收。
- 自动管理内存,避免内存泄漏。
- 缺点:
- 对象的回收时间不可预测,可能导致缓存中的数据丢失。
- 需要额外的管理来处理弱引用。
虚引用(Phantom Reference)
- 定义:虚引用不会阻止对象被垃圾回收,主要用于跟踪对象的回收状态。
- 使用场景:适用于需要跟踪对象回收状态的场景。
- 优点:
- 可以跟踪对象的回收状态。
- 缺点:
- 无法通过虚引用访问对象。
- 需要配合引用队列(Reference Queue)使用。
对比表格
| 特性 | 强引用 (Strong Reference) | 软引用 (Soft Reference) | 弱引用 (Weak Reference) | 虚引用 (Phantom Reference) |
|---|---|---|---|---|
| 定义 | 最常见的引用类型 | 不阻止对象被垃圾回收,内存不足时回收 | 不阻止对象被垃圾回收,没有强引用时回收 | 不阻止对象被垃圾回收,主要用于跟踪对象回收状态 |
| 使用场景 | 大多数对象 | 内存敏感的缓存 | 缓存,避免内存泄漏 | 跟踪对象回收状态 |
| 优点 | 对象不会被垃圾回收 | 内存不足时回收对象,避免内存溢出 | 对象的回收时间可预测,自动管理内存 | 可以跟踪对象的回收状态 |
| 缺点 | 容易导致内存泄漏 | 对象的回收时间不可预测 | 对象的回收时间不可预测 | 无法通过虚引用访问对象 |
| 适用性 | 通用 | 内存敏感的应用 | 缓存管理 | 对象回收状态跟踪 |
| 实现类 | 无特殊类 | java.lang.ref.SoftReference | java.lang.ref.WeakReference | java.lang.ref.PhantomReference |
| 示例 | Object obj = new Object(); | SoftReference<Object> softRef = new SoftReference<>(new Object()); | WeakReference<Object> weakRef = new WeakReference<>(new Object()); | PhantomReference<Object> phantomRef = new PhantomReference<>(new Object(), new ReferenceQueue<>()); |
总结
- 强引用:最常见,确保对象不被垃圾回收,但可能导致内存泄漏。
- 软引用:适用于内存敏感的缓存,内存不足时回收对象。
- 弱引用:适用于缓存管理,自动管理内存,避免内存泄漏。
- 虚引用:用于跟踪对象的回收状态,无法访问对象。
通过理解这些引用类型及其优缺点,可以更好地管理对象的生命周期和内存使用,特别是在实现缓存和内存敏感的应用时。WeakHashMap 利用弱引用来实现自动内存管理,适用于需要缓存的场景。
相关文章:
java的WeakHashMap可以用来做缓存使用?强软弱虚四种引用对比
在 Java 中,引用(Reference)机制用于管理对象的生命周期和垃圾回收。Java 提供了四种类型的引用:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Refer…...
【AVRCP】Notification PDUs 深入解析与应用
目录 一、Notification PDUs 概述 二、GetPlayStatus:同步查询播放状态 2.1 命令功能与应用场景 2.2 请求格式(CT → TG) 2.3 响应格式(TG → CT) 2.4 注意事项 2.5 协议实现示例(伪代码) 三、RegisterNotification:异步事件订阅 3.1 命令概述 3.2 命令格式 …...
从过拟合到强化学习:机器学习核心知识全解析
Langchain系列文章目录 01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…...
【MySQL基础-9】深入理解MySQL中的聚合函数
在数据库操作中,聚合函数是一类非常重要的函数,它们用于对一组值执行计算并返回单个值。MySQL提供了多种聚合函数,如COUNT、SUM、AVG、MIN和MAX等。这些函数在数据分析和报表生成中扮演着关键角色。本文将深入探讨这些聚合函数的使用方法、注…...
Lora 中 怎么 实现 矩阵压缩
Lora 中 怎么 实现 矩阵压缩 1. 导入必要的库 import torch import re from datasets import Dataset from transformers import AutoTokenizer, AutoModelForCausalLM, TrainingArguments, Trainer, \get_cosine_schedule_with_warmup, EarlyStoppingCallback from peft...
MATLAB 控制系统设计与仿真 - 27
状态空间的标准型 传递函数和状态空间可以相互转换,接下来会举例如何有传递函数转成状态空间标准型。 对角标准型 当 G(s)可以写成: 即: 根据上图可知: 约当标准型 当 G(s)可以写成: 即: 根据上图…...
linux 命令 cp
cp 是 Linux 中用于复制文件和目录的命令,基本功能是将源文件或目录复制到目标位置 基本语法 cp [选项] 源文件 目标文件 cp [选项] 源文件1 源文件2 ... 目标目录 常用选项 选项说明-i交互模式(覆盖前询问确认)-r 或 -R递归复制目录&#…...
从FFmpeg命令行到Rust:多场景实战指南
FFmpeg作为功能强大的多媒体处理工具,被广泛应用于视频编辑、格式转换等领域。然而,直接使用FFmpeg的命令行界面(CLI)可能会遇到以下挑战: 命令复杂度高:FFmpeg的命令行参数众多且复杂,初学者可…...
蓝桥杯高频考点——进制转换
进制转换 二进制转十进制代码演示 十六进制转十进制代码演示 十进制转K进制代码演示 任意进制之间的转换代码演示 二进制转十进制 代码演示 // 定义函数 calc,用于将字符转换为对应的数值 int calc(char c) {// 若字符 c 大于等于 9(注:此处…...
【算法百题】专题七_分治快排_专题八_分治归并
文章目录 前言分治快排题:043. [颜⾊分类(medium)](https://leetcode.cn/problems/sort-colors/description/)分析 044. [快速排序(medium)](https://leetcode.cn/problems/sort-an-array/description/)分析 045. [快速…...
DOM4J解析XML, 修改xml的值
1. 引入pom依赖 <dependency><groupId>org.dom4j</groupId><artifactId>dom4j</artifactId><version>2.1.3</version> </dependency> 2. 解析xml, 修改xml节点的值 import org.apache.commons.io.IOUtils; import org.dom4…...
3.16[A]FPGA
FPGA的工作原理是通过配置存储器中的数据来控制可编程逻辑单元和互连资源,从而实现用户定义的逻辑功能。用户可以通过硬件描述语言(HDL)编写代码,然后通过综合、映射、布局布线等步骤生成配置数据,最后将这些数据加载到…...
ssh转发笔记
工作中又学到了,大脑转不过来 现有主机A,主机B,主机C A能访问B,B能访问C,A不能访问C C上80端口有个服务,现在A想访问这个服务,领导让用ssh转发,研究半天没找到理想的语句…...
使用OBS进行webRTC推流参考
参考腾讯云官方文档: 云直播 OBS WebRTC 推流_腾讯云 说明非常详细,分为通过WHIP和OBS插件的形式进行推流。 注意:通过OBS插件的形式进行推流需要使用较低的版本,文档里有说明,需要仔细阅读。...
(链表)面试题 02.07. 链表相交
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。 图示两个链表在节点 c1 开始相交: 题目数据 保证 整个链式结构中不存在环。 注意,函数返回结果后ÿ…...
Python----数据可视化(Pyecharts三:绘图二:涟漪散点图,K线图,漏斗图,雷达图,词云图,地图,柱状图折线图组合,时间线轮廓图)
1、涟漪特效散点图 from pyecharts.globals import SymbolType from pyecharts.charts import EffectScatter from pyecharts.faker import Faker from pyecharts import options as opts from pyecharts.globals import ThemeType # 绘制图表 es (EffectScatter(init_optsop…...
正则表达式:贪婪匹配与非贪婪匹配
正则表达式:贪婪匹配与非贪婪匹配 非贪婪匹配 .*?这三个字符的组合就是非贪婪匹配,意思是匹配任意字符直到遇到第一个后面指定的字符,比如.*?_就表示匹配任意字符直到碰到下划线,还可以组合^来表示从头匹配,比如^.*?_就是从头…...
IP风险度自检,互联网的安全“指南针”
IP地址就像我们的网络“身份证”,而IP风险度则是衡量这个“身份证”安全性的重要指标。它关乎着我们的隐私保护、账号安全以及网络体验,今天就让我们一起深入了解一下IP风险度。 什么是IP风险度 IP风险度是指一个IP地址可能暴露用户真实身份或被网络平台…...
数据结构与算法-图论-拓扑排序
前置芝士 概念 拓扑排序(Topological Sorting)是对有向无环图(DAG,Directed Acyclic Graph)的顶点进行排序的一种算法。它将图中的所有顶点排成一个线性序列,使得对于图中的任意一条有向边 (u, v)&#x…...
Gan网络公式了解
Gan网络 生成器和判别器是亦敌亦友的关系 对于生成模型,损失函数很难定义->所以我们可以将生成模型的输出交给判别模型进行处理,来分辨好坏。 生成器的损失是通过判别器的输出来计算的,而判别器的输出是一个概率值,我们可以通过…...
解决linux mysql命令 bash: mysql: command not found 的方法
首先得知道mysql命令或mysqladmin命令的完整路径 比如mysql的路径是: /usr/local/mysql/bin/mysql,我们则可以这样执行命令: ln -s /usr/local/mysql/bin/mysql /usr/bin © 著作权归作者所有,转载或内容合作请联系作者 喜欢的朋友记得点…...
微服务存在的问题及解决方案
微服务存在的问题及解决方案 1. 存在问题 1.1 接口拖慢 因为一个接口在并发时,正好执行时长又比较长,那么当前这个接口占用过多的 Tomcat 连接,导致其他接口无法即时获取到 Tomcat 连接来完成请求,导致接口拖慢,甚至…...
【css酷炫效果】纯CSS实现立体纸张折叠动效
【css酷炫效果】纯CSS实现悬浮阴影扩散交互 缘创作背景html结构css样式完整代码基础版进阶版(3d 悬浮效果) 效果图 通过CSS box-shadow与transition属性实现悬浮阴影扩散交互,为元素添加细腻的悬浮反馈。 想直接拿走的老板,链接放在这里:htt…...
案例5_1:单位数码管显示0
文章目录 文章介绍效果图仿真图5_1放置单位数码管 代码5_1.c 文章介绍 效果图 仿真图5_1 复制案例1_2的仿真图,在此基础上修改 注意:栅格大小需要缩小 放置单位数码管 代码5_1.c #include <reg52.h>#define uchar unsigned char #define uint un…...
Linux centos7误删/boot拯救方法
1.进入救援模式 插入CentOS 7安装光盘,重启系统。在开机时按BIOS设置对应的按键(通常是F2等),将启动顺序调整为CD - ROM优先。 系统从光盘启动后,选择“Troubleshooting”,然后选择“Rescue a CentOS s…...
操作系统八股文整理(一)
操作系统八股文整理 一、进程和线程的区别二、进程与线程的切换过程一、进程切换进程切换的步骤: 二、线程切换线程切换的步骤: 三、进程切换与线程切换的对比四、上下文切换的优化 三、系统调用一、系统调用的触发二、从用户空间切换到内核空间三、执行…...
20250317笔记本电脑在ubuntu22.04下使用acpi命令查看电池电量
20250317笔记本电脑在ubuntu22.04下使用acpi命令查看电池电量 2025/3/17 18:05 百度:ubuntu查看电池电量 百度为您找到以下结果 ubuntu查看电池电量 在Ubuntu操作系统中,查看电池电量通常可以通过命令行或者图形界面来完成。下面是一些常见的方法&…...
蓝桥杯备考----模拟算法 phone number
嗯。这道题可以在两个和三个数字加-,我们只要随便输出一个奏行 那么!我们规范一下,我们尽可能的只在两个数字之间加,但是如果一共奇数个的话,我们就让最后三个成一组,也就是说,我们用的是个小贪…...
【数据分享】2000—2024年我国省市县三级逐月归一化植被指数(NDVI)数据(Shp/Excel格式)
之前我们分享过2000—2024年逐月归一化植被指数(NDVI)栅格数据(可查看之前的文章获悉详情),该数据来源于NASA定期发布的MOD13A3数据集!很多小伙伴拿到数据后反馈栅格数据不太方便使用,问我们能不…...
算法基础篇(蓝桥杯常考点)
算法基础篇 前言 算法内容还有搜索,数据结构(进阶),动态规划和图论 数学那个的话大家也知道比较难,放在最后讲 这期包含的内容可以看目录 模拟那个算法的话就是题说什么写什么,就不再分入目录中了 注意事…...
