我在link上找到了该文档 它描述如下:
弱引用对于映射有用,一旦它们不再被引用(从外部),它们的条目应自动删除。 SoftReference和WeakReference之间的区别在于决定清除和排列引用的时间点: 应尽可能早地清除和排队SoftReference,即,如果VM存在内存不足的危险。 一旦知道弱引用,就可以清除WeakReference并将其排队。
但是当我查看Dalvikvm的源代码时,在dvmCollectGarbageInternal(Heap.cpp L446 Android 4.4)函数中找到了一些东西。它似乎有两个参考 同时清除。 /*
* All strongly-reachable objects have now been marked. Process
* weakly-reachable objects discovered while tracing.
*/
dvmHeapProcessReferences(&gcHeap->softReferences,
spec->doPreserve == false,
&gcHeap->weakReferences,
&gcHeap->finalizerReferences,
&gcHeap->phantomReferences);
我错过了什么吗?
=============================================== =================================
在@ fadden的帮助下,我找到了保留代码
if (!marked && ((++counter) & 1))
dalvikvm保留每个GC程序的半软件参考,并且我复制某人的测试代码测试
final ArrayList> list = new ArrayList>( SR_COUNT); for(int i = 0; i< SR_COUNT; ++ i){ list.add(new SoftReference(new Integer(i))); }
/* Test */
for (int i = 0; i < 3; ++i) {
System.gc();
try {
Thread.sleep(200);
} catch (final InterruptedException e) {
}
}
/* Check */
int dead = 0;
for (final SoftReference<Integer> ref : list) {
if (ref.get() == null) {
++dead;
}
Log.d(TAG, "dead: " + dead);
}
来自logcat的所有日志都是我的想法。
答案 0 :(得分:2)
FWIW,Java中弱/软/幻像引用的最佳描述见 Java编程语言(“垃圾收集和内存”)的第17章。
软引用保留没有强制性政策。允许VM在GC期间丢弃所有或不丢弃,或者介于两者之间。唯一的要求是在抛出OOM之前,VM应该丢弃所有可轻松访问的对象。
您可以在MarkSweep.cpp的dvmHeapProcessReferences()
中继续使用Dalvik的逻辑。请特别注意对preserveSomeSoftReferences()
的调用,该调用根据引用“颜色”保留一些但不保留其他内容。您可以在wikipedia GC article上阅读有关颜色的更多信息。
答案 1 :(得分:0)
来自理解弱参考,作者:Ethan Nicholas: https://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html
弱引用
简单地说,弱引用是一个不足以强制对象保留在内存中的引用。弱引用允许您利用垃圾收集器为您确定可达性的能力,因此您不必自己执行此操作。您可以创建一个弱引用:
WeakReference weakWidget = new WeakReference(widget);
然后在代码中的其他地方你可以使用weakWidget.get()来获取实际的Widget对象。当然弱引用不足以防止垃圾收集,因此您可能会发现(如果没有对小部件的强引用)weakWidget.get()突然开始返回null。
...
软参考
软引用与弱引用完全相同,只是它不太愿意丢弃它引用的对象。一个只能弱访问的对象(对它的最强引用是WeakReferences)将在下一个垃圾收集周期被丢弃,但是一个可以轻松到达的对象通常会暂停一段时间。
SoftReferences的行为与WeakReferences不同,但实际上只要内存供应充足,就可以保留软可访问对象。这使得它们成为缓存的良好基础,例如上面描述的图像缓存,因为您可以让垃圾收集器担心对象的可达性(永远不会从缓存中移除强可达对象)以及它有多糟糕需要他们消耗的记忆。
Peter Kessler在评论中补充道:
Sun JRE确实以不同于WeakReferences的方式处理SoftReferences。如果可用内存没有压力,我们会尝试保持SoftReference引用的对象。一个细节:“-client”和“-server”JRE的策略是不同的:-client JRE试图通过清除SoftReferences而不是扩展堆来保持您的足迹小,而-server JRE尝试保留您的通过优先扩展堆(如果可能)而不是清除SoftReferences来提高性能。一种尺寸并不适合所有人。