本文介绍了安卓:GC的不尊重SoftReferences?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据接缝的Dalvik的的垃圾回收器不尊重SoftReferences,并尽快删除它们,就像在WeakReferences。我不是100%肯定还没有,但尽管仍然有空闲内存〜3MB我SoftReferences被清除后,我看到GC释放BLA-BLA-BLA字节在LogCat中。

It seams that Dalvik's garbage collector doesn't respect SoftReferences and removes them as soon as possible, just like WeakReferences. I'm not 100% sure yet, but despite the fact that there is still ~3MB of free memory my SoftReferences get cleared after I see "GC freed bla-bla-bla bytes" in LogCat.

另外,我看到一个评论马克·墨菲这里

Also, I saw a comment by Mark Murphy here:

除了它无法正常工作  机器人,至少在1.5  大体时间。我不知道如果GC  SoftReference错误已得到修复。  SoftReferences得到GC'd与太早  这个bug。

是这样吗?难道SoftReferences不尊重呢?

Is it true? Are SoftReferences not respected?

如何解决这个?

推荐答案

在没有收到答案,我决定把我自己的研究。我做了一个简单的测试,以行使对SoftReferences的GC。

After not receiving an answer I decided to make my own study. I've made a simple test to exercise the GC against SoftReferences.

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);
    }
}

我们的想法是,我做出同样的$ C $的几道C对SoftReferences每次增加的压力(通过运行多个GC通行证)。

The idea is that I make few runs of the same code increasing stress on SoftReferences each time (by running more GC passes).

结果是pretty的有趣的:所有试验都通过就好了,除了一个!

Results are pretty interesting: All runs pass just fine except for one!


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.

这些测试结果是稳定的。我试过很多次,每一次都是一样的。因此,我认为这确实是垃圾收集器的错误。

These test results are stable. I've tried many times and every time it is the same. So I believe it is indeed a bug in garbage collector.

所以,我们学习了这个...在code用SoftReferences什么是毫无意义的为Android 1.5-1.6设备。对于这些设备,你会的不可以获得预期的行为。我没有尝试为2.1,但是。

So, what we learn out of this... Using SoftReferences in your code is pointless for Android 1.5-1.6 devices. For these devices you will not get the behavior you expect. I didn't try for 2.1, however.

这篇关于安卓:GC的不尊重SoftReferences?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 12:52