线程对象在完成后不进行垃圾回收

Tom*_*ski 10 debugging android garbage-collection memory-leaks ddms

我注意到我的应用程序正在泄漏内存.这可以在DDMS中看到,我设法得到一个OutOfMemoryError.

我找到了泄漏的来源.其中一个活动有一个在后台运行的线程.此线程已停止onDestroy().它完成了运行,因为它可以在DDMS中看到.

现在,如果线程启动,则发生泄漏,Activity在被销毁后不会被垃圾收集,因为它被线程引用.如果没有启动线程,一切都还可以.

这是一个简单的例子来证明这一点:

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    volatile boolean finished = false;
    byte[] memoryEater = new byte[4 * 1024 * 1024];

    Thread thread = new Thread(new Runnable() {

        @Override
        public void run() {
            while (!finished) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            Log.d(getClass().getName(), "Thread finished");
        }
    });

    @Override
    protected void onDestroy() {
        super.onDestroy();
        finished = true;
    }

    public void startActivity(View view) {
        startActivity(new Intent(this, MainActivity.class));
    }

    public void startThread(View view) {
        thread.start();
    }
}
Run Code Online (Sandbox Code Playgroud)

添加一个按钮用于启动新活动,另一个用于启动线程.开始新的活动.返回后,仅在线程尚未启动时才会清除内存.

这种行为的原因是什么?

小智 13

我刚刚想出了同样的问题.

托马斯,你走在正确的轨道上.DDMS中没有错误,程序中没有内存泄漏.

真正的问题是你在DEBUG模式下运行你的程序(在Eclipse下).不知何故,当Android在DEBUG模式下运行时,即使在退出run()方法之后,线程也不会被垃圾回收.我想这可能是Android需要坚持使用Thread以使某些调试功能正常工作.

但是如果您在RUN模式下运行应用程序(仍在Eclipse下),则会发生Thread垃圾收集.Thread将被完全释放,您的Activity将被完全释放.