一、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. golang type conversion

    map[string]interface{} is not the same as map[string]string. Type interface{} is not the same as typ ...

  2. 红米k30评测+全面解读

    暂时还没有图片等页面美化..其实网上有很多美图,这里不再粘贴了 红米k30是小米公司子品牌红米最近推出的一款性价比非常高的手机,以下进行多方面解读: 本人会尽量用不懂手机都能理解的语言来各方面讲解k3 ...

  3. Zabbix Web 中文字体显示问题

  4. flutter TextField 输入框被软键盘挡住的解决方案

    以前搞ionic1~4的开发中 和react-native   flutter中的机制完全不同, 在flutter 中 当前页面如果存在元素被软键盘挡住 的情况 页面元素的最外层肯定得嵌套一层   S ...

  5. 方程的解——枚举&&水题

    题目 链接 给出方程组:$$\displaystyle \left\{\begin{aligned}11x + 13y + 17z = 2471 \\13x + 17y + 11z = 2739\en ...

  6. 关于 ESIM 网络的 资料 集合

    1.https://blog.csdn.net/wcy23580/article/details/84990923 原理及Python keras 实现 2.https://www.kaggle.co ...

  7. vue-cli 3.x 修改dist路径和在本地查看方法

    打包文件路径问题 需要在项目的根目录添加一个vue.config.js.在这个文件中,我们可以进行一些个性化定制. module.exports = { // 基本路径 baseUrl: './', ...

  8. JavaWeb_(Hibernate框架)Hibernate论坛项目中多对多案例

    基于SSH论坛小型项目 传送门 用户和发帖进行举例 多对多关系:多个用户可以回复多个帖子 因此引入了一张回复表,用来保存用户id和帖子id CREATE TABLE `hforum`.`answer` ...

  9. 预处理、const、static与sizeof-为什么要引入内联函数

    1:引入内联函数的主要目的是,用它替代C语言中表达形式的宏定义来解决程序中函数调用的效率问题.在C语言里可以使用如下的宏定义: #define ExpressionName(Var1,Var2) (V ...

  10. 预处理、const、static与sizeof-用#define实现宏并求最大值和最小值

    1:实现代码: #define MAX(x,y) (((x)>(y)) ? (x):(y)) #define MIN(x,y) (((x)>(y)) ? (x):(y)) 需要注意的几点: ...