java weakhashmap用法_Java WeakHashMap指南
概述
在这篇文章中,我们将探索 java.util 包中的WeakHashMap。
为了理解数据结构,我们将在这里使用它来推出一个简单的缓存实现。但是,请记住,这是为了了解地图的工作原理,并且创建自己的缓存实现几乎总是一个坏主意。
简而言之,WeakHashMap是Map接口的基于哈希表的实现,其键为WeakReference类型。
当WeakHashMap中的某个条目不再被普通使用时,该条目将被自动删除,这意味着没有单个Reference 指向该键。当垃圾回收(GC)进程丢弃某个键时,其条目将有效地从映射中删除,因此此类的行为与其他Map实现有所不同。
Strong, Soft, and Weak References
要了解WeakHashMap的工作原理,我们需要查看WeakReference类 -这是WeakHashMap实现中键的基本构造。在Java中,我们有三种主要的引用类型,我们将在以下各节中进行解释。
强引用
强引用是我们在日常编程中使用的最常见的引用类型:
Integer prime = 1; 变量prime具有对值为1 的Integer对象的强引用。任何具有指向其的强引用的对象均不适合使用GC。
弱引用
简而言之,只有在JVM绝对需要内存之前,才会对具有SoftReference 指向该对象的对象进行垃圾回收。
让我们看看如何在Java中创建SoftReference:
Integer prime = 1;
SoftReference soft = new SoftReference(prime);
prime = null;
该主要对象有指向它很强的借鉴意义。
接下来,我们将主要的强引用包装为软引用。将强引用设为null之后,素对象可以使用GC,但仅在JVM绝对需要内存时才收集该对象。
虚引用
仅弱引用所引用的对象会被紧急收集;在这种情况下,GC不会等到需要内存。
我们可以通过以下方式在Java中创建WeakReference:
Integer prime = 1;
WeakReference soft = new WeakReference(prime);
prime = null;
当我们将主要引用设为null时,主要对象将在下一个GC周期中被垃圾回收,因为没有其他强引用指向该对象。
WeakReference类型的引用在WeakHashMap中用作键。
WeakHashMap作为高效的内存缓存
假设我们要建立一个缓存,将大图像对象保留为值,并将图像名称保留为键。我们想选择一个合适的地图实现来解决该问题。
使用简单的HashMap将不是一个好的选择,因为值对象可能会占用大量内存。而且,即使它们不再在我们的应用程序中使用,它们也永远不会被GC进程从缓存中回收。
理想情况下,我们需要一个Map实现,该实现允许GC自动删除未使用的对象。当我们的应用程序中任何地方都没有使用大图像对象的键时,该条目将从内存中删除。
幸运的是,WeakHashMap具有这些特征。让我们测试一下WeakHashMap并观察其行为:
WeakHashMap map = new WeakHashMap<>();
BigImage bigImage = new BigImage("image_id");
UniqueImageName imageName = new UniqueImageName("name_of_big_image");
map.put(imageName, bigImage);
assertTrue(map.containsKey(imageName));
imageName = null;
System.gc();
await().atMost(10, TimeUnit.SECONDS).until(map::isEmpty);
我们正在创建一个WeakHashMap实例,该实例将存储我们的BigImage对象。我们将BigImage对象作为值,并将imageName对象引用作为键。的imageName将被存储在一个图作为WeakReference的类型。
接下来,我们将imageName引用设置为null,因此不再有指向bigImage对象的引用。WeakHashMap的默认行为是在下一个GC上回收没有引用的条目,因此该条目将在下一个GC进程中从内存中删除。
我们正在调用System.gc()来强制JVM触发GC进程。GC周期结束后,我们的WeakHashMap将为空:
WeakHashMap map = new WeakHashMap<>();
BigImage bigImageFirst = new BigImage("foo");
UniqueImageName imageNameFirst = new UniqueImageName("name_of_big_image");
BigImage bigImageSecond = new BigImage("foo_2");
UniqueImageName imageNameSecond = new UniqueImageName("name_of_big_image_2");
map.put(imageNameFirst, bigImageFirst);
map.put(imageNameSecond, bigImageSecond);
assertTrue(map.containsKey(imageNameFirst));
assertTrue(map.containsKey(imageNameSecond));
imageNameFirst = null;
System.gc();
await().atMost(10, TimeUnit.SECONDS)
.until(() -> map.size() == 1);
await().atMost(10, TimeUnit.SECONDS)
.until(() -> map.containsKey(imageNameSecond));
请注意,只有imageNameFirst引用设置为null。该imageNameSecond参考保持不变。触发GC后,映射将仅包含一个条目– imageNameSecond。
java weakhashmap用法_Java WeakHashMap指南相关推荐
- java list用法_Java List 用法详解及实例分析
Java List 用法详解及实例分析 Java中可变数组的原理就是不断的创建新的数组,将原数组加到新的数组中,下文对Java List用法做了详解. List:元素是有序的(怎么存的就怎么取出来,顺 ...
- java treemap用法_Java TreeMap put()用法及代码示例
TreeMap的java.util.TreeMap.put()方法用于将映射插入Map.这意味着我们可以将特定的键及其映射到的值插入到特定的映射中.如果传递了现有键,则以前的值将被新值替换.如果传递了 ...
- java future用法_Java中的多线程知识点
如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个话其 ...
- java return用法_Java枚举的高级用法之多键值的映射使用
枚举Enum单映射使用 做Java的各位仁兄姐妹都知道,Java通过HashMap,以及枚举提供了方便的K-V映射功能,例如 枚举单映射使用 但是如果遇到多个键值映射,例如K-K-V的形式怎么办呢?可 ...
- java foreach用法_Java十大简单性能优化
以下是Java中最容易进行的10个性能优化: 1.使用StringBuilder 这几乎是所有Java代码中的默认设置.尽量避免+操作员.当然,您可能会争辩说它StringBuilder无论如何都是语 ...
- java list用法_java list的用法详解
java list的用法详解 java中可变数组的原理就是不断的创建新的数组,将原数组加到新的数组中.以下是百分网小编搜索整理的关于java list的用法详解,需要的朋友可以参考一下!想了解更多相关 ...
- java instanceof用法_Java基础高频面试题汇总(1.4W字详细解析)
注:由于公众号文章推送规则的改变,所以为了大家能够准时收到我们的文章推送,请记得将公众号:JAVA编程语言 设为星标-这样就不会错过每一篇精彩的推送啦~ 1. Java语言有哪些特点 (1)简单易学. ...
- java pattern用法_Java Pattern和Matcher用法
Pattern用法 Java正则表达式通过java.util.regex包下的Pattern和Matcher类实现 Pattern类用于创建一个正则表达式,也可以说是创建一个匹配模式,可以通过两个静态 ...
- equals java的用法_Java ConcurrentLinkedDeque equals()用法及代码示例
java.util.ConcurrentLinkedDeque类的equals()方法用于比较指定对象与此ConcurrentLinkedDeque是否相等.当且仅当指定对象也是ConcurrentL ...
最新文章
- request 对象和 response 对象
- python时间变量_python的对象 变量
- 哈尔滨商业大学计算机与信息工程学院地址,计算机与信息工程学院
- “大数据系统软件国家工程实验室”建设项目通过验收
- xib自动布局的时候,label高度计算误差问题
- ECCV2020论文-稀疏性表示-Neural Sparse Representation for Image Restoration翻译
- python调试网页_Python Django shell 调试
- 【通知】2020年有三AI-CV夏季划升级,更多项目,更高难度,更加落地
- mysql 整个数据库_mysql 整个数据库
- web前端常用知识点
- 最小二乘估计_相关性及最小二乘估计【20201026】
- C# 实现将文本txt生成图片
- ajax全局加密,Ajax请求接口加密研究(针对网页前端的接口安全加密机制研究)...
- 「mac操作指南」WidsMob HEIC将HEIC/HEIF 转换为 JPEG/PNG/TIFF格式
- 新版IAR软件打开旧版本创建的项目时出现的三个错误及其解决方案 is too long for segment definition
- 《多媒体技术与应用》练习题
- 42步进电机转速力矩曲线_42步进电机转速范围说明(28步进电机转速测试)
- Android MVVM框架搭建(一)ViewModel + LiveData + DataBinding
- JAVA中将汉字转化为首字母大写或拼音的格式
- 内窥镜胶囊(胶囊内镜)硬件方案
热门文章
- R方差分析(anova)以及Tukey检验
- LDNFSGB: prediction of long non-coding rna and disease association using network feature similarity
- oracle ora 13011,ORA-00600: internal error code, arguments: [13011]
- 电脑服务器高配置和高性能,为高性能工作站服务 超算系统配置推荐
- java中怎么放入.jpg_Java如何设置jpg质量
- tensorflow tf.keras.losses.MeanSquaredError 均方差损失函数 示例
- pycharm的anaconda配置
- 【Kaidi安装问题】下载mkl过慢
- oracle 加号和on,Oracle中连接与加号(+)的使用
- python mysql 分页_利用python对mysql表做全局模糊搜索并分页实例