diff --git a/notes/Java 容器.md b/notes/Java 容器.md index 4cad3006..c6fc88f4 100644 --- a/notes/Java 容器.md +++ b/notes/Java 容器.md @@ -13,6 +13,7 @@ * [HashMap](#hashmap) * [ConcurrentHashMap](#concurrenthashmap) * [LinkedHashMap](#linkedhashmap) + * [WeekHashMap](#weekhashmap) * [参考资料](#参考资料) @@ -982,6 +983,63 @@ public static void main(String[] args) { [3, 1, 4] ``` +## WeekHashMap + +### 存储结构 + +WeakHashMap 的 Entry 继承自 WeakReference,被 WeakReference 关联的对象在下一次垃圾回收时会被回收。 + +WeakHashMap 主要用来实现缓存,通过使用 WeakHashMap 来引用缓存对象,由 JVM 对这部分缓存进行回收。 + +```java +private static class Entry extends WeakReference implements Map.Entry +``` + +### ConcurrentCache + +Tomcat 中的 ConcurrentCache 就使用了 WeakHashMap 来实现缓存功能。 + +ConcurrentCache 采取的是分代缓存: + +- 经常使用的对象放入 eden 中,eden 使用 ConcurrentHashMap 实现,不用担心会被回收(伊甸园); +- 不常用的对象放入 longterm,longterm 使用 WeakHashMap 实现,用来存放比较老的对象,这些老对象会被垃圾收集器回收。 + +```java +public final class ConcurrentCache { + + private final int size; + + private final Map eden; + + private final Map longterm; + + public ConcurrentCache(int size) { + this.size = size; + this.eden = new ConcurrentHashMap<>(size); + this.longterm = new WeakHashMap<>(size); + } + + public V get(K k) { + V v = this.eden.get(k); + if (v == null) { + v = this.longterm.get(k); + if (v != null) + this.eden.put(k, v); + } + return v; + } + + public void put(K k, V v) { + if (this.eden.size() >= size) { + this.longterm.putAll(this.eden); + this.eden.clear(); + } + this.eden.put(k, v); + } +} +``` + + # 参考资料 - Eckel B. Java 编程思想 [M]. 机械工业出版社, 2002. diff --git a/notes/Java 虚拟机.md b/notes/Java 虚拟机.md index 552a5e94..3bb9f289 100644 --- a/notes/Java 虚拟机.md +++ b/notes/Java 虚拟机.md @@ -184,49 +184,6 @@ WeakReference wf = new WeakReference(obj); obj = null; ``` -WeakHashMap 的 Entry 继承自 WeakReference,主要用来实现缓存。 - -```java -private static class Entry extends WeakReference implements Map.Entry -``` - -Tomcat 中的 ConcurrentCache 就使用了 WeakHashMap 来实现缓存功能。ConcurrentCache 采取的是分代缓存,经常使用的对象放入 eden 中,而不常用的对象放入 longterm。eden 使用 ConcurrentHashMap 实现,longterm 使用 WeakHashMap,保证了不常使用的对象容易被回收。 - -```java -public final class ConcurrentCache { - - private final int size; - - private final Map eden; - - private final Map longterm; - - public ConcurrentCache(int size) { - this.size = size; - this.eden = new ConcurrentHashMap<>(size); - this.longterm = new WeakHashMap<>(size); - } - - public V get(K k) { - V v = this.eden.get(k); - if (v == null) { - v = this.longterm.get(k); - if (v != null) - this.eden.put(k, v); - } - return v; - } - - public void put(K k, V v) { - if (this.eden.size() >= size) { - this.longterm.putAll(this.eden); - this.eden.clear(); - } - this.eden.put(k, v); - } -} -``` - **(四)虚引用** 又称为幽灵引用或者幻影引用。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用取得一个对象实例。