Java 集合 持有引用 & WeakHashMap
Java 集合 持有引用 & WeakHashMap
@author ixenos
摘要:强引用、弱引用、WeakHashMap动态回收步骤
Reference引用对象
- 可获得的(reachable):指在栈中有一个普通的引用正在指向此对象,也可能有更多的中间链接
如果一个对象是可获得的,垃圾回收器(GC)就不能释放它,因为他仍然为程序所用,宁愿耗尽内存也不释放;当一个对象不是可获得的时候,程序无法使用它,此时GC才认为将其回收是安全的
Reference对象:如果想继续持有对某个对象的引用,但也希望能够允许GC释放它,就应使用Reference对象作为与普通引用之间的媒介(代理),即普通引用经Reference对象包装过再指向某个对象
普通引用-->Reference对象-->目标对象
Reference引用对象的四种分类(由强到弱)
强引用(Strong Reference):强引用时,就是普通引用,对象是可获得的(reachable)
软引用(Soft Reference):实现内存敏感的高速缓存 //TODO
- 弱引用(Weak Reference):实现规范映射(canonicalizing mappings),它不妨碍GC回收映射的key或value,规范映射中对象的实例可以在程序的多处被同时使用,以节省存储空间
- 幻象引用(Phantom Reference):用以调度回收前的清理工作,比Java终止机制灵活
幻象引用于弱引用和软引用均不同。它控制其指向的对象非常弱(tenuous),以至于它不能获得这个对象。get()方法通常情况下返回的是null值。它唯一的作用就是跟踪列队在ReferenceQuene中的已经死去的对象。
幻象引用和弱引用的不同在于其入队(enquene)进入ReferenceQuene的方式。当弱引用的对象成为若可到达时,弱引用即列队进入ReferenceQuene。这个入队发生在终结(finialize)和垃圾回收实际发生之前。理论上,通过不正规(unorthodox)的finilize()方法,成为垃圾的对象能重新复活(resurrected),但是弱引用仍然是死的。幻象引用只有当对象在物理上从内存中移出时,才会入队。这就阻止我们重新恢复将死的对象。
W:终结(Finalization)指比拉圾回收更一般的概念,可以回收对象所占有的任意资源,比如文件描述符和图形上下文等。
幻象引用由两个好处:
A:它能确定某一个对象从内存中移除的时间,这也是唯一的方式。通常情况下,这不是非常有用。但是迟早(come in handy)会用到手动处理大图片的情况:如果你确定一张图片需要被垃圾回收,那么在你尝试加载下一张照片前,你应该等待这张照片被回收完成。这样就使得令人恐惧的(dreaded)内存溢出不太可能发生。
B:虚幻引用能够避终结(finilize)的基本问题。finilize()方法能够通过给一个垃圾对象关联一个强引用使之复活。问题是覆写了finilize()方法的对象在成为垃圾之前,为了回收,垃圾回收期需要执行两次单独的循环。第一轮循环确定某个对象是垃圾,那么它就符合终结finilize的条件。在finilize的过程中,这个对象可能被“复活”。在这个对象被实际移除之前,垃圾回收期不得不重新运行一遍。因为finilization并不是实时调用的,所以在终止进行的过程中,可能发生了gc的多次循环。在实际清理垃圾对象时,这导致了一些延时滞后。这将导致Heap中有大量的垃圾导致内存溢出。
幻象引用不可能发生以上的情况,当幻象引用入队时,它实际上已经被移除了内存。幻象内存无法“复活”对象。这发现这个对象时虚幻可到达时,在第一轮循环中,它就被回收。
可以证明,finilize()方法从不在第一种情况下使用,但是虚幻引用提供了一种更安全和有效的使用和被排除掉的finilize方法的机制,使得垃圾回收更加简单。但是因为有太多的东西需要实现,我通常不适用finilize。幻象引用原理
ReferenceQueue引用队列
使用软引用和弱引用时们可以选择是否要将他们放入ReferenceQueue(用作“回收前清理工作”的工具),而幻象引用回收后进入ReferenceQueue
幻象引用和弱引用的不同在于其入队(enquene)进入ReferenceQuene的方式:
当弱引用的对象成为若可到达时,弱引用即列队进入ReferenceQuene。这个入队发生在终结(finialize)和垃圾回收实际发生之前。理论上,通过不正规(unorthodox)的finilize()方法,成为垃圾的对象能重新复活(resurrected),但是弱引用仍然是死的,因为没有引用指向它;
而幻象引用只有当对象在物理上从内存中移出时,才会入队。这就阻止我们重新恢复将死的对象;
终结(Finalization)指比拉圾回收更一般的概念,可以回收对象所占有的任意资源,比如文件描述符和图形上下文等
以弱引用为例
一旦弱引用返回null值,那么其指向的对象就变成了垃圾,这个弱引用对象也就没有用了。这通常意味着要进行一定方式的清理(cleanup)。例如,WeakHashmap将会移除一些死的(dread)的entry,避免持有过多死的弱引用。ReferenceQuene能够轻易的追踪这些死掉的弱引用;
可以将ReferenceQuene传入WeakHashmap的构造方法(constructor)中,这样,一旦这个弱引用指向的对象成为垃圾,这个弱引用将加入ReferenceQuene中
WeakHashMap弱散列映射表
WeakHashMap使用弱引用(WeakReference)保存键,称为弱键
ref-->weak ref-->key , if (ref==null) , than ( weak ref-->ref queue , WeakHashMap将删除对应的条目)
- 动态回收的步骤:
(1) 新建WeakHashMap,将“键值对”添加到WeakHashMap中
将“键值对”添加到WeakHashMap中时,添加的键都是弱键;实际上,WeakHashMap是通过数组table保存Entry(键值对);每一个Entry实际上是一个单向链表,即Entry是键值对链表;
(2) 当某“弱键”不再被其它对象引用,并被GC回收时。在GC回收该“弱键”时,这个“弱键”也同时会被添加到queue队列中
例如,当我们在将“弱键”key添加到WeakHashMap之后;后来将key设为null。这时,便没有外部外部对象再引用该了key;接着,当Java虚拟机的GC回收内存时,会回收key的相关内存;同时,将key添加到queue队列中;
(3) 当下一次我们需要操作WeakHashMap时,会先同步table和queue。table中保存了全部的键值对,而queue中保存被GC回收的“弱键”;同步它们,就是删除table中被GC回收的“弱键”对应的键值对
例如,当我们“读取WeakHashMap中的元素或获取WeakReference的大小时”,它会先同步table和queue,目的是“删除table中被GC回收的‘弱键’对应的键值对”。删除的方法就是逐个比较“table中元素的‘键’和queue中的‘键’”,若它们相当,则删除“table中的该键值对”。
-
Java 集合 持有引用 & WeakHashMap的更多相关文章
- Java 集合系列 13 WeakHashMap
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- Java 集合系列 09 HashMap详细介绍(源码解析)和使用示例
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- Java 集合系列 10 Hashtable详细介绍(源码解析)和使用示例
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- Java 集合系列 17 TreeSet
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- Java 集合系列 16 HashSet
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- Java 集合系列 15 Map总结
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- Java 集合系列 14 hashCode
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- Java 集合系列 12 TreeMap
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- Java 集合系列 11 hashmap 和 hashtable 的区别
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
随机推荐
- 转载--初识绘图工具plantUML
原文出处:http://www.jianshu.com/p/e92a52770832 什么是 PlantUML PlantUML 是一个画图脚本语言,用它可以快速地画出: 时序图 流程图 用例图 状态 ...
- JDK安装(CentOS/rpm方式)
1. 用如下命令检验是否已经自带了OpenJDK java -version 如果打印如下,则表示安装了OpenJDK java version "1.6.0" OpenJDK R ...
- yarn的调度器
三种调度器 1.FIFO Scheduler 把应用按提交的顺序排成一个队列,这是一个先进先出队列,在进行资源分配的时候,先给队列中最头上的应用进行分配资源,等最前面的应用需求满足后再给下一个分配,以 ...
- idea中建立maven web项卡在Generating Project in Batch mode
Maven命令执行到Generating Project in Batch mode 卡住,原因是网络带宽不足问题!需要下载一个约5.1M的xml文件. Maven一般命令:mvn archetype ...
- 【noi openjudge题解】最低通行费
这道题完全没有必要去计算限制时间,把时间当做一个参数来做就行了.知道了这一点之后就可以直接使用DP求解了 #include <algorithm> #include <iostrea ...
- 关闭Pycharm拼写检查(Mac)
1.关闭拼写检查,preference-->Editor-->Inspections-->Spelling-->Typo,取消勾选 2.关闭代码风格检查,preference- ...
- mysql5.5修改字符编码
因为mysql版本问题,网上各种修改编码的方法都不行,最后找到下面这条,终于解决! [mysqld]下添加: character-set-server=utf8 collation-server=ut ...
- flask安装首页显示
参考:http://flask.pocoo.org/1.安装和测试[root@node1 flask]#pip install flaskd[root@node1 flask]# cat app.py ...
- Django ORM操作
ORM 常用操作进阶操作 #!/usr/bin/env python #_*_ coding:utf8 _*_ from __future__ import unicode_literals from ...
- Sublime的Package Control的安装
最近在用Sublime,我想很多人和我一样都是先要安装PackageControl吧! 可是看了网上的好多博客感觉都太繁琐了 对于像我这样的小白来说实在有很多看不懂的地方 相对来说还是官网的那种方法更 ...