一、JAVA中的四种引用类型

  1、强引用(StrongReference):强引用是最为普遍的一种引用,如果对象被强引用,那么垃圾回收器无论如何都不会回收它,当内存不足时会抛出OutOfMemoryError异常。

  2、软引用(SoftReference):如果一个对象只被软引用,当内存空间足够时,垃圾回收器就不会回收它。当内存空间不足时,该对象就会被回收。

  3、弱引用(WeakReference):如果一个对象只被弱引用,触发GC时,不管内存是否足够,垃圾回收器都会将其回收。

  4、虚引用(PhantomReference):如果一个对象只有虚引用在引用它,垃圾回收器是可以在任意时候对其进行回收的,虚引用主要用来跟踪对象被垃圾回收器回收的活动。

二、WeakHashMap源码分析

  由于WeakHashMap的源码和HashMap差不多,所以只说一些特别的地方。

  1、WeakHashMap对于键值对的引用类型为弱引用,WeakHashMap定义了一个ReferenceQueue来储存已经被回收了的键值对,当我们需要获取某个键值对的时候会先利用ReferenceQueue将WeakHashMap中已经被回收的键值对清除掉。

        /**
* 用来存储已经被GC的entry
*/
private final ReferenceQueue<Object> queue = new ReferenceQueue<>(); /**
* 从表中删除陈旧的条目,通过和ReferenceQueue中进行对比,来进行删除
*/
private void expungeStaleEntries() {
for (Object x; (x = queue.poll()) != null; ) {
synchronized (queue) {
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>) x;
int i = indexFor(e.hash, table.length); Entry<K,V> prev = table[i];
Entry<K,V> p = prev;
while (p != null) {
Entry<K,V> next = p.next;
if (p == e) {
if (prev == e)
table[i] = next;
else
prev.next = next;
// Must not null out e.next;
// stale entries may be in use by a HashIterator
e.value = null; // Help GC
size--;
break;
}
prev = p;
p = next;
}
}
}
}

...

private Entry<K,V>[] getTable() {
expungeStaleEntries();
return table;
} public int size() {
if (size == 0)
return 0;
expungeStaleEntries();
return size;
} public boolean isEmpty() {
return size() == 0;
} public V get(Object key) {
Object k = maskNull(key);
int h = hash(k);
Entry<K,V>[] tab = getTable();
int index = indexFor(h, tab.length);
Entry<K,V> e = tab[index];
while (e != null) {
if (e.hash == h && eq(k, e.get()))
return e.value;
e = e.next;
}
return null;
}

  

  2、WeakHashMap的Entry类继承了WeakReference类,其构造函数中有一个参数queue用来传入父类构造函数中,ReferenceQueue用来保存被GC的Entry。

Entry(Object key, V value, ReferenceQueue<Object> queue, int hash, Entry<K,V> next)

  3、WeakHashMap的初始化默认参数和HashMap相同,但是其hash方法以及resize方法不同。扩容的时候容量也是将容量变为原来的两倍

    final int hash(Object k) {
int h = k.hashCode(); // This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
} /**
* 确定entry的下标位置
*/
private static int indexFor(int h, int length) {
return h & (length-1);
}

java数据结构之WeakHashMap的更多相关文章

  1. Java数据结构之队列的实现以及队列的应用之----简单生产者消费者应用

    Java数据结构之---Queue队列 队列(简称作队,Queue)也是一种特殊的线性表,队列的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置插入和删除,而队列只允许在 ...

  2. JAVA数据结构系列 栈

    java数据结构系列之栈 手写栈 1.利用链表做出栈,因为栈的特殊,插入删除操作都是在栈顶进行,链表不用担心栈的长度,所以链表再合适不过了,非常好用,不过它在插入和删除元素的时候,速度比数组栈慢,因为 ...

  3. Java数据结构之树和二叉树(2)

    从这里始将要继续进行Java数据结构的相关讲解,Are you ready?Let's go~~ Java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来 ...

  4. Java数据结构之树和二叉树

    从这里开始将要进行Java数据结构的相关讲解,Are you ready?Let's go~~ Java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来的 ...

  5. Java数据结构之线性表(2)

    从这里开始将要进行Java数据结构的相关讲解,Are you ready?Let's go~~ java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来的 ...

  6. Java数据结构之线性表

    从这里开始将要进行Java数据结构的相关讲解,Are you ready?Let's go~~ java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来的 ...

  7. java 数据结构 图

    以下内容主要来自大话数据结构之中,部分内容参考互联网中其他前辈的博客,主要是在自己理解的基础上进行记录. 图的定义 图是由顶点的有穷非空集合和顶点之间边的集合组成,通过表示为G(V,E),其中,G标示 ...

  8. java 数据结构 队列的实现

    java 数据结构队列的代码实现,可以简单的进行入队列和出队列的操作 /** * java数据结构之队列的实现 * 2016/4/27 **/ package cn.Link; import java ...

  9. java 数据结构 栈的实现

    java数据结构之栈的实现,可是入栈,出栈操作: /** * java数据结构之栈的实现 * 2016/4/26 **/ package cn.Link; public class Stack{ No ...

随机推荐

  1. string::crbegin string::crend

    const_reverse_iterator crbegin() const noexcept;功能:crbegin是最后一个字符,crend第一个字符的前一个.迭代器向左移动是“+”,向右移动是“- ...

  2. Oracle 连接排序

    ---左联操作SELECT e.* FROM hs_opt_ewb e left join hs_workform_main m on e.ewb_no=m.ewb_nowhere e.ewb_no= ...

  3. Centos6.5 下安装配置Apache+PHP+Mysql环境

    1.准备工作 # yum -y update && yum -y install vim make cmake gcc gcc-c++ bison bison-devel ncurse ...

  4. springmvc处理一个请求的全流程

    首先,用户的浏览器发出了一个请求,这个请求经过互联网到达了我们的服务器. Servlet 容器首先接待了这个请求,并将该请求委托给 DispatcherServlet 进行处理. 接着 Dispatc ...

  5. oracle impdp 覆盖导入 table_exists_action关键字使用

    oracle10g之后impdp的table_exists_action参数table_exists_action选项:{skip 是如果已存在表,则跳过并处理下一个对象:append是为表增加数据: ...

  6. js中showModalDialog的使用

    基本介绍:          showModalDialog()         (IE 4+ 支持)          showModelessDialog()      (IE 5+ 支持)    ...

  7. BZOJ 1116 [POI2008]CLO-Toll 并查集

    如果一个连通块是一个树的形态,则不合法,否则合法. 用并查集判断一下即可. #include <bits/stdc++.h> #define N 100005 #define M 2000 ...

  8. mybatis 多级级联(多级嵌套)

    注:笔者这里的嵌套可以用词有点欠缺,忘见谅 需求:用一个查询接口查出其结果集,这里就用伪代码标识要返回前端的类与类之间的关系. class 顶层{ String otherValue; LinkedL ...

  9. python小技巧之把list组合成chain

    a=[] for i in range(10): a.append(i) for i,j in zip(a[:-1],a[1:]): print('%s=>%s'%(i,j)) 输出结果: 0= ...

  10. 使用 suspend 和 resume 暂停和恢复线程

    suspend 和 resume 的使用 在 Thread 类中有这样两个方法:suspend 和 resume,这两个方法是成对出现的. suspend() 方法的作用是将一个线程挂起(暂停), r ...