使用弱引用是我从未见过的实现,所以我试图弄清楚它们的用例是什么以及实现如何工作.什么时候需要使用WeakHashMap
或者WeakReference
它是如何使用的?
强引用的一个问题是缓存,特别是对于像图像这样的非常大的结构.假设您有一个必须使用用户提供的图像的应用程序,例如我工作的网站设计工具.当然,您希望缓存这些图像,因为从磁盘加载它们非常昂贵,并且您希望避免在内存中同时存储两个(可能是巨大的)图像副本的可能性.
因为当我们不绝对需要时,图像缓存应该阻止我们重新加载图像,你会很快意识到缓存应该总是包含对已经在内存中的任何图像的引用.但是,对于普通的强引用,引用本身会强制图像保留在内存中,这需要您以某种方式确定内存中何时不再需要该图像并将其从缓存中删除,以使其符合垃圾回收的条件.您被迫复制垃圾收集器的行为并手动确定对象是否应该在内存中.
理解弱参考,Ethan Nicholas
要明确的一个区别是a WeakReference
和a 之间的区别SoftReference
.
基本上WeakReference
,一旦被引用的对象没有硬引用,JVM就会急切地想要GC-d .一个SoftReference
在另一方面d对象,往往会被垃圾收集器留约,直到它真正需要回收内存.
将值保存在WeakReference
s中的缓存将是非常无用的(在a中SoftReference
,它是弱引用的键).WeakReference
当您想要实现可以使用可用内存增长和缩小的缓存时,可以将值包装起来
WeakReference
s和WeakHashMap
s的一个常见用途是用于向对象添加属性.有时您希望向对象添加一些功能或数据,但子类和/或组合不是一个选项,在这种情况下,显而易见的事情是创建一个hashmap,将您想要扩展的对象链接到要添加的属性.然后,无论何时您需要房产,您都可以在地图上查找.但是,如果要添加属性的对象倾向于被破坏并且被创建很多,则最终会导致地图中的许多旧对象占用大量内存.
如果您使用的WeakHashMap
是对象,只要程序的其余部分不再使用它们就会离开您的地图,这是所需的行为.
我不得不这样做是为了增加一些数据,以java.awt.Component
避开在1.4.2和1.5之间的JRE的变化,我可以通过继承每个组件我很感兴趣,INT(固定它JButton
,JFrame
,JPanel
...),但是,这是多少使用更少的代码更容易.
对于另一个有用的情况WeakHashMap
和WeakReference
是一个听众注册表实现.
当你创建想要听某些事件的东西时,通常你会注册一个监听器,例如
manager.registerListener(myListenerImpl);
如果manager
将监听器存储为a WeakReference
,则表示您不需要删除寄存器,例如a,manager.removeListener(myListenerImpl)
因为一旦您的监听器或持有监听器的组件变得不可用,它将自动删除.
当然你仍然可以手动删除你的监听器,但是如果你没有或你忘了它,它不会导致内存泄漏,并且它不会阻止你的监听器被垃圾收集.
WeakHashMap
图片在哪里?
用于存储已注册的侦听器的侦听器注册表WeakReference
需要一个集合来存储这些引用.WeakHashSet
标准Java库中没有实现,WeakHashMap
但我们可以轻松地使用后者来"实现"第一个的功能:
SetlistenerSet = Collections.newSetFromMap(new WeakHashMap ());
使用此listenerSet
命令注册一个新的侦听器,您只需将其添加到集合中,即使未显式删除它,如果不再引用侦听器,它也将由JVM自动删除.