gpt4 book ai didi

Android:GC 不尊重 SoftReferences?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:06:33 27 4
gpt4 key购买 nike

看起来 Dalvik 的垃圾收集器不尊重 SoftReferences 并尽快删除它们,就像 WeakReferences 一样。我还不是 100% 确定,但尽管事实上仍有大约 3MB 的可用内存,但在我在 LogCat 中看到“GC freed bla-bla-bla bytes”后,我的 SoftReferences 被清除了。

此外,我还看到了 Mark Murphy 的评论 here :

Except that it doesn't work on Android, at least in the 1.5 timeframe. I have no idea if the GC SoftReference bugs have been fixed. SoftReferences get GC'd too soon with this 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);
}
}

我的想法是,我每次运行相同的代码都会增加对 SoftReferences 的压力(通过运行更多的 GC 遍数)。

结果非常有趣:除了一次以外,所有运行都顺利通过!

On Android 1.5 device:testSoftRefsAgainstGc_1()  FAILED!  AssertionFailedError: expected:0 but was:499testSoftRefsAgainstGc_2()  passedtestSoftRefsAgainstGc_3()  passedtestSoftRefsAgainstGc_4()  passedtestSoftRefsAgainstGc_5()  passedtestSoftRefsAgainstGc_6()  passedtestSoftRefsAgainstGc_7()  passedOn Android 1.6 device:testSoftRefsAgainstGc_1()  passedtestSoftRefsAgainstGc_2()  FAILED!  AssertionFailedError: expected:0 but was:499testSoftRefsAgainstGc_3()  passedtestSoftRefsAgainstGc_4()  passedtestSoftRefsAgainstGc_5()  passedtestSoftRefsAgainstGc_6()  passedtestSoftRefsAgainstGc_7()  passedOn Android 2.2 device:All pass.

这些测试结果是稳定的。我试过很多次,每次都是一样的。所以我相信这确实是垃圾收集器中的一个错误。

结论

因此,我们从中学到了什么......在您的代码中使用 SoftReferences 对于 Android 1.5-1.6 设备毫无意义。对于这些设备,您将不会获得您期望的行为。但是,我没有尝试 2.1。

关于Android:GC 不尊重 SoftReferences?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4014033/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com