关键: 为何HashMap 一个容器对象仍是处于WeakHashMapjava
1. 以弱键 实现的基于哈希表的 Map。在 WeakHashMap 中,当某个键再也不正常使用时,将自动移除其条目。更精确地说,对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,而后被回收。丢弃某个键时,其条目从映射中有效地移除编程
2. WeakHashMap 类的行为部分取决于垃圾回收器的动做。由于垃圾回收器在任什么时候候均可能丢弃键,WeakHashMap 就像是一个被悄悄移除条目的未知线程。特别地,即便对 WeakHashMap 实例进行同步,而且没有调用任何赋值方法,在一段时间后 size 方法也可能返回较小的值,对于 isEmpty 方法,返回 false,而后返回true,对于给定的键,containsKey 方法返回 true 而后返回 false,对于给定的键,get 方法返回一个值,但接着返回 null,对于之前出如今映射中的键,put 方法返回 null,而 remove 方法返回 false,对于键 set、值 collection 和条目 set 进行的检查,生成的元素数量愈来愈少。缓存
3. WeakHashMap 中的每一个键对象间接地存储为一个弱引用的指示对象。所以,无论是在映射内仍是在映射以外,只有在垃圾回收器清除某个键的弱引用以后,该键才会自动移除。安全
引用类型的分类:编程语言
1 强引用 - Strong Referenceui
2 弱引用 - Weak Referencespa
3软引用 - Soft Reference线程
4 幻想引用 - Phantom Referencecode
到目前为止:你对于WeakHashMap有了一个基本的概念,可是仍是比较模糊,接下来,咱们对于orm
java 引用的内容进行一个详尽头解析
1 :强引用
Stringbuffer sb = new StringBuffer();
Person p = new Person();
Stringbuilder sb = new StrignBuilder();
这句代码建立了一个StringBuffer对象,在变量buffer中存储了这个对象的一个强引用。强引用之因此称之为“强”(Strong),是由于他们与垃圾回收器(garbage collector)交互的方式。特别是(specifically),若是一个对象经过强引用链接(strongly reachable-强引用可到达),那么它就不在垃圾回收期处理之列。当你正在使用某个对象而不但愿垃圾回收期销毁这个对象时,强引用一般正好能知足你所要的。
2. 当强引用太强的时候
假定你要使用一个final类Widget,可是基于某种缘由,你不能继承(extend)这个类或者经过其余方法为这个类增长一些新的功能。若是你须要跟踪(track)这个类的不一样对象的序列号。那么能够将这些对象放入HashMap中,得到不一样的value值,这样就能够作到经过不一样的value值跟踪这些对象了。代码:
serialNumberMap.put(widget, widgetSerialNumber);
可是widget的强引用会产生一些问题。在咱们不须要一个Widget的序列号时,咱们须要将这个Widget对应的Entry从HashMap中移除。不然咱们可能面临内存泄露(memory leak)的问题(若是咱们没有在应当移除Widgt的时候移除它),或者咱们将莫名其妙的丢失序列号(若是咱们正在使用Widget时却移除了它)。若是这些问题相似,那么这些问题是无垃圾回收机制(non-garbage-collected language)的编程语言的开发者所面临的问题。Java的开发者不须要担忧这种问题。
W:若是一个对象具备强引用,那就相似于必不可少的生活用品,垃圾回收器毫不会回收它。当内存空 间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具备强引用的对象来解决内存不足问题。
强引用的另一个常见问题就是图片缓存(cache)。普通的强引用将使得Image继续保存在内存中。在一些状况下,咱们不须要有些Image继续留在内存中,咱们须要将这些图片从内存中移出,这时,咱们将扮演垃圾回收期的角色来决定哪些照片被移除。使这些被移出的图片被垃圾回收器销毁。下一次,你被迫再次扮演垃圾回收期的角色,手动决定哪些Image被回收。
Note:我以为也能够用对象的hashCode来跟踪对象。做者在此所举的例子,只在说明Strong Reference。
3. 弱引用

简单说,就是弱引用不足以将其链接的对象强制保存在内存中。弱引用可以影响(leverage)垃圾回收器的某个对象的可到达级别。代码:
WeakReference<Widget> weakWidget = new WeakReference<Widget>(widget);
你可使用weakWidget.get()方法老获取实际的强引用对象。可是在以后,有可能忽然返回null值(若是没有其余的强引用在Widget之上),由于这个弱引用被回收。其中包装的Widget也被回收。
解决Widget序列号的问题,最简单的方法就是使用WeakHashmap。其key值为弱引用。若是一个WeakHashmap的key变成垃圾,那么它对应用的value也自动的被移除。
W:垃圾回收期并不会总在第一次就找到弱引用,而是会找几回才能找到。
4. 引用队列(Reference Quene)
一旦弱引用返回null值,那么其指向的对象(即Widget)就变成了垃圾,这个弱引用对象(即weakWidget)也就没有用了。这一般意味着要进行必定方式的清理(cleanup)。例如,WeakHashmap将会移除一些死的(dread)的entry,避免持有过多死的弱引用。
ReferenceQuene可以轻易的追踪这些死掉的弱引用。能够讲ReferenceQuene传入WeakHashmap的构造方法(constructor)中,这样,一旦这个弱引用指向的对象成为垃圾,这个弱引用将加入ReferenceQuene中。
以下图所示:

5. 软引用
除了在抛出本身所指向的对象的迫切程度方面不同以外,软引用和弱引用基本同样。一个对象为弱可到达(或者指向这个对象的强引用是一个弱引用对象-即强引用的弱引用封装),这个对象将在一个垃圾回收循环内被丢弃。可是,弱引用对象会保留一段时间以后才会被丢弃。
软引用的执行和弱引用并无任何不一样。可是,在供应充足(in plentiful supply)的状况下,软可到达对象将在内存中保存尽量长的时间。这使得他们在内存中有绝佳的存在基础(即有尽量长存在的基础)。由于你让垃圾回收器去担忧两件事情,一件是这个对象的可到达性,一件是垃圾回收期多么想要这些对象正在消耗的内存。
6. 幻象引用(phantom reference)
幻象引用于弱引用和软引用均不一样。它控制其指向的对象很是弱(tenuous),以致于它不能得到这个对象。get()方法一般状况下返回的是null值。它惟一的做用就是跟踪列队在ReferenceQuene中的已经死去的对象。
幻象引用和弱引用的不一样在于其入队(enquene)进入ReferenceQuene的方式。当弱引用的对象成为若可到达时,弱引用即列队进入ReferenceQuene。这个入队发生在终结(finialize)和垃圾回收实际发生以前。理论上,经过不正规(unorthodox)的finilize()方法,成为垃圾的对象能从新复活(resurrected),可是弱引用仍然是死的。幻象引用只有当对象在物理上从内存中移出时,才会入队。这就阻止咱们从新恢复将死的对象。
W:终结(Finalization)指比拉圾回收更通常的概念,能够回收对象所占有的任意资源,好比文件描述符和图形上下文等。
幻象引用由两个好处:
A:它能肯定某一个对象从内存中移除的时间,这也是惟一的方式。一般状况下,这不是很是有用。可是早晚(come in handy)会用到手动处理大图片的状况:若是你肯定一张图片须要被垃圾回收,那么在你尝试加载下一张照片前,你应该等待这张照片被回收完成。这样就使得使人恐惧的(dreaded)内存溢出不太可能发生。
B:虚幻引用可以避终结(finilize)的基本问题。finilize()方法可以经过给一个垃圾对象关联一个强引用使之复活。问题是覆写了finilize()方法的对象在成为垃圾以前,为了回收,垃圾回收期须要执行两次单独的循环。第一轮循环肯定某个对象是垃圾,那么它就符合终结finilize的条件。在finilize的过程当中,这个对象可能被“复活”。在这个对象被实际移除以前,垃圾回收期不得不从新运行一遍。由于finilization并非实时调用的,因此在终止进行的过程当中,可能发生了gc的屡次循环。在实际清理垃圾对象时,这致使了一些延时滞后。这将致使Heap中有大量的垃圾致使内存溢出。
幻象引用不可能发生以上的状况,当幻象引用入队时,它实际上已经被移除了内存。幻象内存没法“复活”对象。这发现这个对象时虚幻可到达时,在第一轮循环中,它就被回收。
能够证实,finilize()方法从不在第一种状况下使用,可是虚幻引用提供了一种更安全和有效的使用和被排除掉的finilize方法的机制,使得垃圾回收更加简单。可是由于有太多的东西须要实现,我一般不适用finilize。
W:Object类中相关内容以下:

文档中相关内容以下:
