WeakHashMap和强引用值 [英] WeakHashMap and strongly referenced value

查看:181
本文介绍了WeakHashMap和强引用值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Javadocs说:当某个键已被废弃时,它的输入被有效地从地图中删除。



但除非有另一个线程有时会删除此类(Map.Entry)条目,值对象是否不会被地图强烈引用?但由于没有这样的线程运行,只有 get 方法调用可以删除这样的条目 - 一次一个。



我几乎总是使用 WeakHashMap< K,WeakReference< V>> 。为什么它们不会将默认行为 - 值作为弱引用?

解决方案

引用队列用于自动删除条目。



http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/ref/ReferenceQueue.html


引用队列,在检测到适当的可达性更改之后,垃圾回收器将向其添加注册引用对象。


基本上,弱引用是垃圾收集器的核心部分,因此当GC扫描发生时,未使用的引用被找到并放入队列,然后可以基于这些队列的内容采取行动。 / p>

线程可以位于队列的 remove 方法在需要清理或 poll 的队列。



Java理论与实践:用弱引用插入内存泄漏解释:


WeakHashMap 的实现说明了一个有弱引用的常见习语 - 某些内部对象扩展 WeakReference p>

...



WeakHashMap 映射密钥,它们允许当应用程序不再使用密钥对象时进行垃圾收集,并且 get()实现可以告诉死锁映射通过 WeakReference.get()是否返回 null 。但这只是在应用程序的整个生命周期内保持Map的内存消耗增加所需的一半;在收集密钥对象之后,还必须执行从地图修剪死条目的操作。 否则,Map只会填充对应于死锁的条目。虽然这对于应用程序是不可见的,但它仍然可能导致应用程序耗尽内存,因为Map.Entry和值即使键是



...



引用队列是垃圾收集器将信息反馈给应用程序关于对象生命周期的主要手段。弱引用具有两个构造函数:一个仅使用指示对象作为参数,另一个也使用引用队列。当已经使用相关联的引用队列创建了弱引用并且引用对象变为GC的候选者时,在引用被清除之后,引用对象(而不是引用对象)在引用队列上排队。然后,应用程序可以从引用队列中检索引用,并了解引用对象已被收集,因此它可以执行关联的清除活动,例如清除已从弱集合中删除的对象的条目。 (参考队列提供与BlockingQueue相同的出列模式 - 轮询,定时阻塞和无限块阻塞。)


编辑:



即使有队列,弱地图仍然可能泄漏。 Ephemerons 试图解决弱键引用引用键的强保持值的情况。它们不能在java中实现。


ephemerons解决了通过使用注册表尝试附加属性到对象时常见的问题。当一些属性应该被附加到对象时,属性应该(根据GC行为)通常具有该对象的实例变量将具有的生命时间。然而,通过在对象及其属性之间具有外部关联,这是复杂的:

  property ------ --- registry --------- association --------- object 

在这里,注册表(第三方)将持有关联本身,这将需要从注册表手动删除(而不是自动垃圾回收)。虽然这个问题总是可以通过使用各种弱关联类型之一在任何给定的具体情况下解决,但选择正确类型的关联取决于各种因素,其中一些可以动态改变。



ephemerons通过定义一个星历的内容(值)将被强有力地解决这个问题,直到知道该键被垃圾收集。从那时起,星历的内容将保持弱。因此,当且仅当密钥是垃圾收集时,星历的内容才能成为垃圾收集的对象,这是我们将观察对象的实例变量的确切行为。



Javadocs says "When a key has been discarded its entry is effectively removed from the map".

But unless there is another thread that occasionally removes such (Map.Entry) entries, won't the value objects be strongly referenced by the map? But since there is no such thread running, only the get method invocations can remove such entries - one at a time.

I almost always use WeakHashMap<K,WeakReference<V>> for that reason. Why would they not have made that the default behavior - values as weak references too?

解决方案

Reference queues are used to automatically remove entries.

http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/ref/ReferenceQueue.html

Reference queues, to which registered reference objects are appended by the garbage collector after the appropriate reachability changes are detected.

Basically, weak references are a core part of the garbage collector, so when a GC sweep happens, unused references are found and put onto queues and then action can be taken based on the content of those queues.

A thread can sit on the queue's remove method to be alerted when cleanup needs to be done or poll the queue.

"Java theory and practice: Plugging memory leaks with weak references" explains:

The implementation of WeakHashMap illustrates a common idiom with weak references -- that some internal object extends WeakReference.

...

WeakHashMap uses weak references for holding map keys, which allows the key objects to be garbage collected when they are no longer used by the application, and the get() implementation can tell a live mapping from a dead one by whether WeakReference.get() returns null. But this is only half of what is needed to keep a Map's memory consumption from increasing throughout the lifetime of the application; something must also be done to prune the dead entries from the Map after the key object has been collected. Otherwise, the Map would simply fill up with entries corresponding to dead keys. And while this would be invisible to the application, it could still cause the application to run out of memory because the Map.Entry and value objects would not be collected, even if the key is.

...

Reference queues are the garbage collector's primary means of feeding back information to the application about object lifecycle. Weak references have two constructors: one takes only the referent as an argument and the other also takes a reference queue. When a weak reference has been created with an associated reference queue and the referent becomes a candidate for GC, the reference object (not the referent) is enqueued on the reference queue after the reference is cleared. The application can then retrieve the reference from the reference queue and learn that the referent has been collected so it can perform associated cleanup activities, such as expunging the entries for objects that have fallen out of a weak collection. (Reference queues offer the same dequeuing modes as BlockingQueue -- polled, timed blocking, and untimed blocking.)

EDIT:

Even with queues, weak maps can still leak. Ephemerons are an attempt to solve the case where a weak key references a strongly held value that references the key. They are not implementable in java.

Ephemerons solve a problem which is commonly found when trying to "attach" properties to objects by using a registry. When some property should be attached to an object, the property should (in terms of GC behavior) typically have the life-time that an instance variable of this object would have. However, this is complicated by having an external association between the object and its property such as:

property --------- registry --------- association --------- object

Here, the registry (a third party) will hold onto the association itself which would require manual removal from the registry (instead of automated garbage collection). While this problem can always be solved in any given concrete situation by using one of the various weak association types, choosing the 'right' kind of association depends on a variety of factors some of which can change dynamically.

Ephemerons solve this problem by defining that the 'contents' (value) of an ephemeron will be held strongly until the key is known to be garbage collected. From then on, the contents of the ephemeron will be held weakly. Therefore, the contents of an ephemeron can become eligible for garbage collection if and only if the key is garbage collectable which is the exact behavior which we would observe for an instance variable of the object.

这篇关于WeakHashMap和强引用值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆