JBM*_*JBM 10 android garbage-collection weak-references soft-references
它接收Dalvik的垃圾收集器不尊重SoftReferences并尽快删除它们,就像WeakReferences一样.我还不是100%肯定,但是在我看到LogCat中的"GC释放bla-bla-bla字节"之后,我的SoftReferences仍然被释放了大约3MB的可用内存.
另外,我看到马克·墨菲评论这里:
除非它在Android上不起作用,至少在1.5时间范围内.我不知道GC SoftReference错误是否已修复.SoftReferences很快就会遇到这个bug.
这是真的吗?SoftReferences不受尊重吗?
如何解决这个问题?
在没有得到答案后,我决定自己学习.我做了一个简单的测试来对抗SoftReferences来运行GC.
public class TestSoftReference extends TestCase {
public void testSoftRefsAgainstGc_1() { testGcWithSoftRefs(1); }
public void testSoftRefsAgainstGc_2() { testGcWithSoftRefs(2); }
public void testSoftRefsAgainstGc_3() { testGcWithSoftRefs(3); }
public void testSoftRefsAgainstGc_4() { testGcWithSoftRefs(4); }
public void testSoftRefsAgainstGc_5() { testGcWithSoftRefs(5); }
public void testSoftRefsAgainstGc_6() { testGcWithSoftRefs(6); }
public void testSoftRefsAgainstGc_7() { testGcWithSoftRefs(7); }
private static final int SR_COUNT = 1000;
private void testGcWithSoftRefs(final int gc_count) {
/* "Integer(i)" is a referrent. It is important to have it referenced
* only from the SoftReference and from nothing else. */
final ArrayList<SoftReference<Integer>> list = new ArrayList<SoftReference<Integer>>(SR_COUNT);
for (int i = 0; i < SR_COUNT; ++i) {
list.add(new SoftReference<Integer>(new Integer(i)));
}
/* Test */
for (int i = 0; i < gc_count; ++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;
}
}
assertEquals(0, dead);
}
}
Run Code Online (Sandbox Code Playgroud)
我的想法是每次运行相同的代码,增加对SoftReferences的压力(通过运行更多的GC传递).
结果非常有趣:除了一个之外,所有的跑步都很好!
On Android 1.5 device: testSoftRefsAgainstGc_1() FAILED! AssertionFailedError: expected:0 but was:499 testSoftRefsAgainstGc_2() passed testSoftRefsAgainstGc_3() passed testSoftRefsAgainstGc_4() passed testSoftRefsAgainstGc_5() passed testSoftRefsAgainstGc_6() passed testSoftRefsAgainstGc_7() passed On Android 1.6 device: testSoftRefsAgainstGc_1() passed testSoftRefsAgainstGc_2() FAILED! AssertionFailedError: expected:0 but was:499 testSoftRefsAgainstGc_3() passed testSoftRefsAgainstGc_4() passed testSoftRefsAgainstGc_5() passed testSoftRefsAgainstGc_6() passed testSoftRefsAgainstGc_7() passed On Android 2.2 device: All pass.
这些测试结果稳定.我已经尝试了很多次,每次都是一样的.所以我相信它确实是垃圾收集器中的一个错误.
所以,我们从中学到了什么...在Android 1.5-1.6设备中使用代码中的SoftReferences 是没有意义的.对于这些设备,您将无法获得预期的行为.但是,我没有尝试使用2.1.
| 归档时间: |
|
| 查看次数: |
1903 次 |
| 最近记录: |