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 ...
随机推荐
- 打印java堆栈信息
使用如下命令: kill -3 {pid} 可以打印指定线程的堆栈信息到tomcat的catalina.out日志中.在性能测试过程中,可以观察响应时间的曲线,如果突然出现波峰则抓取当前时间点tomc ...
- C语言考试可能会涉及到的内容
以下是汽院下属科院C(B)考试范围,C(A)的话,不考的内容应该都会涉及到,重点内容会延伸至三.四章. 一.教材上的两套自测题 二.C语言实验与实训教程 第一章.第二章.第三章.第四章的典型练习及解释 ...
- JSON跟JSONP的区别以及实战
前言 由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现. 当然了,通过调用强大的PhoneGap插件然后打包,你可以实现100%的Socke ...
- Java 后台sql注入
JdbcTemplate.update(sql, ArrayList.toArray()) Connection conn = null; PreparedStatement ps = null; c ...
- NGINX----源码阅读---cycle
/* * Copyright (C) Igor Sysoev * Copyright (C) Nginx, Inc. */ #ifndef _NGX_CYCLE_H_INCLUDED_#define ...
- angular-file-upload+springMVC的使用
最近项目中需要用到文件上传,使用了angular-file-upload插件完成 首先来介绍下这个插件的一些属性(参考官方文档) FileUploader 属性 url {String}: 上传文件的 ...
- CSS 效果汇总
只要决心够, 就能征服痛苦. 把一些常用的 CSS 效果记录下来 1. 利用 z-index :hover 显示层 github 效果地址>> 此效果主要利用 a:hover 来改变 sp ...
- Python学习笔记——基础篇【第七周】———进程、线程、协程篇(socket基础)
http://www.cnblogs.com/wupeiqi/articles/5040823.htmlhttp://i.cnblogs.com/EditPosts.aspx?postid=55437 ...
- Pelican主题配置:elegant
简介 elegant是Mac风格的优秀主题,简单,专注文章本身. A responsive, minimal, and stylish theme for Pelican:https://github ...
- Android服务
开启服务 (startservice) 服务一旦开启与调用者没有任何的关系 , 调用着的activity 即便是退出了 也不会影响 后台的service的运行. 在activity里面 不能去调用服务 ...