虚弱的HashMap?
这个嘛。。。也可以这么翻译。它也是对HashMap的包装,比较特殊的地方就在于内部的Entry
可能会被GC(垃圾收集)自动删除,即使没有手动调用remove()方法或者clear()方法。
要理解这个Weak,那就需要引入一个概念:弱引用。
我们都知道Java中内存管理是通过GC自动管理的,GC会在程序运行过程中自动判断哪些对象是可以被回收的,并在合适的时机进行内存释放。GC判断某个对象是否可被回收的依据是,是否有有效的引用指向该对象。如果没有有效引用指向该对象(基本意味着不存在访问该对象的方式),那么该对象就是可回收的。这里的有效引用并不包括弱引用。也就是说,虽然弱引用可以用来访问对象,但进行垃圾回收时弱引用并不会被考虑在内,仅有弱引用指向的对象仍然会被GC掉。
将一对key, value
放入到 WeakHashMap 里并不能避免该key
值被GC回收,除非在 WeakHashMap之外还有对该key
的强引用。
在Java中,引用(Reference)是一种特殊的对象,它允许我们引用其他对象,但不会阻止这些对象被垃圾回收器(GC)回收。Java提供了四种类型的引用:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)。下面分别介绍这四种引用以及它们的管理方式:
强引用(Strong Reference):
- 这是最常见的引用类型,比如
Object obj = new Object()
,就是强引用。 - 只要强引用还存在,垃圾回收器永远不会回收被引用的对象。
- 强引用不能被垃圾回收器回收,因此容易造成内存泄漏。
- 这是最常见的引用类型,比如
软引用(Soft Reference):
- 软引用通过
java.lang.ref.SoftReference
类实现。 - 软引用可以被垃圾回收器回收,当内存不足时,垃圾回收器会回收软引用指向的对象来释放内存。
- 软引用通常用于缓存,当内存足够时,缓存可以保持,当内存不足时,可以回收缓存来释放内存。
- 软引用通过
弱引用(Weak Reference):
- 弱引用通过
java.lang.ref.WeakReference
类实现。 - 弱引用指向的对象只能生存到下一次垃圾回收发生之前。当垃圾回收器工作时,无论内存是否足够,都会回收只被弱引用指向的对象。
- 弱引用常用于实现缓存,例如
java.lang.ref.WeakHashMap
。
- 弱引用通过
虚引用(Phantom Reference):
- 虚引用通过
java.lang.ref.PhantomReference
类实现。 - 一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来获取一个对象的实例。
- 虚引用主要用于跟踪对象被垃圾回收的活动,当对象即将被垃圾回收器回收时,会收到一个系统通知。
- 虚引用通过
管理方式:
引用队列(Reference Queue):
- 引用对象可以与一个引用队列(
java.lang.ref.ReferenceQueue
)关联。 - 当垃圾回收器准备回收一个对象时,它会把与该对象相关联的引用放入引用队列中。
- 应用程序可以通过轮询引用队列来发现哪些对象即将被回收,并执行一些清理工作。
- 引用对象可以与一个引用队列(
主动清理:
- 应用程序可以主动检查引用队列,以确定是否有引用需要被清理。
- 这通常在应用程序的某个部分,如缓存管理系统中实现。
自动清理:
- 某些容器类,如
WeakHashMap
和SoftReferenceHashMap
,会自动管理其条目的生命周期,当引用的对象被垃圾回收时,容器会自动移除这些条目。
- 某些容器类,如
使用软引用和弱引用可以帮助减少内存泄漏的风险,并允许垃圾回收器在内存不足时回收对象,这对于管理有限的资源非常有用。然而,它们也增加了程序的复杂性,因为需要正确地管理引用的生命周期。
WeakHashMap
是 Java 中的一个线程不安全的哈希表实现,它继承自 AbstractMap
类,并且实现了 Map
接口。WeakHashMap
的键(Key)是弱引用,这意味着如果键的对象没有任何强引用指向它,那么这个键可以被垃圾回收器回收,即使 WeakHashMap
本身还持有这个键的弱引用。
以下是 WeakHashMap
的一些特点:
键是弱引用:
WeakHashMap
的键是弱引用,这意味着如果一个键没有被其他强引用所引用,那么它可能会在任何时候被垃圾回收器回收。
自动清理:
WeakHashMap
维护了一个引用队列(ReferenceQueue
),当键被垃圾回收器回收时,这个键会被放入引用队列中。WeakHashMap
会定期检查这个队列,并移除那些已经被回收的键。
线程不安全:
WeakHashMap
不是线程安全的,如果在多线程环境中使用,需要外部同步。
用途:
WeakHashMap
通常用于缓存,特别是当缓存项应该在内存不足时被回收的情况。
内存敏感的应用:
- 在内存敏感的应用中,
WeakHashMap
可以用来减少内存消耗,因为它允许垃圾回收器在需要时回收键。
- 在内存敏感的应用中,
迭代器行为:
WeakHashMap
的迭代器在迭代过程中可能会遇到NullPointerException
,因为迭代过程中可能会有键被回收。
与
HashMap
的比较:- 与
HashMap
相比,WeakHashMap
的主要区别在于键的生命周期不是由WeakHashMap
控制的,而是由垃圾回收器控制。
- 与
使用 WeakHashMap
时需要注意的是,由于键是弱引用,所以不能保证 WeakHashMap
中的所有键值对都会一直存在,它们可能会在任何时候被垃圾回收器清除。因此,在使用 WeakHashMap
时,需要考虑到这一点,并在代码中适当处理可能的 NullPointerException
。
(了解一下就行了,平时开发很少用的)
2024.10.29
writeBy kaiven