android - 线程对象在完成后未被垃圾回收

标签 android debugging memory-leaks garbage-collection ddms

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

我找到了泄漏的源头。其中一个 Activity 有一个线程在后台运行。此线程在 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();
    }
}

添加一个用于启动新 Activity 的按钮和一个用于启动线程的按钮。开始新的 Activity 。回去后只有线程没有启动才会清理内存。

这种行为的原因是什么?

最佳答案

我刚刚发现了同样的问题。

Tomasz,你走在正确的轨道上。 DDMS 中没有错误,您的程序中也没有内存泄漏。

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

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

关于android - 线程对象在完成后未被垃圾回收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11640390/

相关文章:

r - 你怎么知道R中的哪些函数被标记为调试?

php - 为什么我在使用 $item->get_permalink() 时会在 SimplePie 中发生内存泄漏?

c - 这个程序正确吗?

python进程每天都在增加内存使用量

java - 为什么 java/android 需要在 XML 元素的开头有一个空格来解析它?

java - 以编程方式添加多种 View 类型的 RecyclerView

android - HTML 电子邮件未在 Android 电子邮件上显示完整宽度

java - OpenWeatherMap API : Encounter NullPointerException

java - 无法使用 eclipse 开始调试 java 应用程序

c++ - MFC - 在 DLL 卸载时扫描我的代码以查找任何剩余的计时器、事件、线程等