线程对象在完成后不会收集垃圾 [英] Thread objects not garbage collected after being finished

查看:124
本文介绍了线程对象在完成后不会收集垃圾的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到我的应用程序正在泄漏内存。这可以在DDMS中看到,I
设法得到一个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(菜单菜单){
getMenuInflater()。inflate(R.menu.activity_main,menu);
返回true;
}

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

Thread thread = new Thread(new Runnable(){

@Override
public void run(){
while(!finished){
尝试{
Thread.sleep(100);
} catch(InterruptedException e){
// TODO自动生成的catch块
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();
}
}

添加一个启动新活动的按钮,一个用于启动一个线程开始新活动返回后,只有线程尚未启动时,内存将被清除。



这种行为的原因是什么?

解决方案

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



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



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



但是,如果您以RUN模式运行应用程序(仍在Eclipse下)线程垃圾回收发生。线程将被完全释放,您的活动将被完全释放。


I noticed that my application is leaking memory. This can be seen in DDMS, and I managed to get a OutOfMemoryError.

I found the source of the leak. One of the activities has a thread running in the background. This thread is stopped in onDestroy(). It finishes running, as it can be seen in DDMS.

Now, if thread is started, the leak occurs, Activity is not garbage collected after being destroyed, because it is referenced by the thread. If thread is not started at all, everything is ok.

Here's simple example demonstrating this:

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

Add one button for starting new activity and one for starting a thread. Start new activity. After going back, the memory will be cleaned only if thread has not been started.

What is the cause of this behaviour?

解决方案

I have just figured out this same problem.

Tomasz, you are on the right track. There is NO bug in DDMS and there is NO memory leak in your program.

The really problem is you are running your program in DEBUG mode (under Eclipse). Somehow when Android is running in DEBUG mode, Threads are not garbage collected even after the run() method has been exited. I guess it is probably Android needs to hold on to the Thread for some debugging features to work.

But if you run you application in RUN mode (still under Eclipse), Thread garbage collection takes place. The Thread will be freed completely and your Activity will be freed completely.

这篇关于线程对象在完成后不会收集垃圾的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆