简单的空白活动导致内存泄漏。为什么?

时间:2013-05-02 08:04:35

标签: android memory-leaks

为了测试,我创建了两个活动

public class TestActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setDisplayShowHomeEnabled(true);

        setContentView(R.layout.activity_bpm);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                Intent intent = new Intent(TestActivity.this, TestActivity2.class);
                startActivity(intent);
                break;
            default:
                return super.onOptionsItemSelected(item);
        }

        return true;
    }
}

public class TestActivity2 extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setDisplayShowHomeEnabled(true);

        setContentView(R.layout.activity_about);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                Intent intent = new Intent(TestActivity2.this, TestActivity.class);
                startActivity(intent);
                break;
            default:
                return super.onOptionsItemSelected(item);
        }

        return true;
    }
}

然后我只是经常按下主页按钮来切换它们和我在LogCat中看到的内容:

05-02 15:55:36.211: D/dalvikvm(15615): GC_CONCURRENT freed 116K, 4% free 7548K/7812K, paused 4ms+2ms, total 20ms
05-02 15:55:40.301: D/dalvikvm(15615): GC_CONCURRENT freed 79K, 3% free 7853K/8080K, paused 2ms+2ms, total 24ms
05-02 15:55:43.611: D/dalvikvm(15615): GC_CONCURRENT freed 97K, 3% free 8189K/8432K, paused 1ms+10ms, total 53ms
05-02 15:55:50.171: D/dalvikvm(15615): GC_CONCURRENT freed 93K, 3% free 8492K/8732K, paused 5ms+9ms, total 44ms
05-02 15:55:53.021: D/dalvikvm(15615): GC_CONCURRENT freed 93K, 3% free 8788K/9028K, paused 2ms+5ms, total 35ms
05-02 15:55:54.861: D/dalvikvm(15615): GC_CONCURRENT freed 96K, 3% free 9116K/9360K, paused 2ms+9ms, total 48ms
05-02 15:55:57.061: D/dalvikvm(15615): GC_CONCURRENT freed 116K, 3% free 9504K/9768K, paused 2ms+7ms, total 45ms

你可以看到用过的内存增长了。所以我有一个问题:这怎么可能? 请解释一下是否有人有线索。

4 个答案:

答案 0 :(得分:1)

这里没有“内存泄漏”的证据。

内存泄漏可能是无法释放内存的情况。从你提出的几个数字来看,这是不可能的;此外,代码并不表示您正在创建内存泄漏。

然而,由Android决定何时物理删除不再可见的Activity对象;毕竟,有后退键,返回它后,旧的Activity仍然在内存中更有效。

Android将Activity实例视为不同,因为它无法对其内部状态做出假设。因此,您正在创建一个不断增长的已访问Activity对象的历史记录列表。当Android从内存中删除旧版本时,会保存其Intent和任何InstanceState Bundle信息。

这些数字不同的事实也归功于垃圾收集者的政策。毕竟,你的Activity对象并不是沿途创建的唯一对象;还会创建几个用户界面对象,垃圾收集器不需要总是释放所有内存,因为它正在运行。它也可以决定它已经释放了足够的内存并为下一轮留下了一些东西。

答案 1 :(得分:0)

这是因为当您运行新活动时,之前的活动不会被破坏并继续使用内存。您可以按返回键返回。

答案 2 :(得分:0)

这里似乎没有内存泄漏。并发GC运行不是内存泄漏的证据,因为它可能决定不收集所有非活动对象。

您可以尝试使用System.gc()显式调用GC,这将(通常)强制垃圾收集器运行并收集所有过期的对象。

在您的情况下,请尝试在System.gc()方法中调用onCreate(),然后查看应用内存是否继续增长。这样,您可以确定您的代码是否泄漏了内存。

答案 3 :(得分:0)

让我们调用TestActivity A和TestActivity2 B,然后在堆栈中第一次从A开始B A - > B.当你从B开始A时,堆栈将是A - > B - > A然后A - > B - > A - > B.所以你可以看到堆栈正在增长 尝试来回几次,然后按后退键,在进入主屏幕之前需要进行相当多的后退按键操作。