How do I fix this Android memory leak involving Threads?

孤街醉人 提交于 2019-12-23 08:29:34

问题


So I've found, with the MAT that I keep creating multiple Threads with every surfaceCreate

I think I need these threads, though, but this method causes multiple instances of ViewThread, as a user navigates through my app, which is a memory leak.

How can I reorganize the way my threads are created and handled so that this doesn't happen, or how can I stop the leak from occurring?

@Override
public void surfaceCreated(SurfaceHolder holder) {
    loading=false;
    if (!mThread.isAlive()){
        mThread = new ViewThread(this);
        mThread.setMenuRunning(true);
        mThread.start();
    }
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {

    if (mThread.isAlive()){ 
        mThread.setMenuRunning(false);
    }
}

I opened and navigated away from the Career Activity of my game five times, and this is what shows up on the MAT

EDIT: I've since found that depending on surfaceDestroyed for the destruction of my threads is unreliable. I now call the appropriate thread-destroying calls from a different method, triggered onPause.


回答1:


You should use a WeakReference to reference the Career in your Thread. This way the reference will be cleared when there are no more hard references to the Career.

You can track all references in MAT by right clicking the career and choosing Path To GC Roots, then with all references. This will show you the path(s) to the object retained in memory. Make sure you either clear those references when you are done with the activity or make use of WeakReferences to have the GC clear them automatically.




回答2:


Inside surfaceDestroyed, you should wait to make sure that the thread stopped before you return.

You can refer to this question, for more details

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    boolean retry = true;
    mThread.setRunning(false);
    while (retry) {
        try {
            mThread.join();
            retry = false;
        } catch (InterruptedException e) {
        }
    }
}



回答3:


So I fixed it by commenting one line:

@Override
public void surfaceCreated(SurfaceHolder holder) {
    loading=false;
    if (!mThread.isAlive()){
        //mThread = new ViewThread(this);
        mThread.setMenuRunning(true);
        mThread.start();
    }
}

This was also combined with the WeakReference and the SurfaceDestroyed answers. I'll test it later and determine if it's just the removal of that one line, or a combination of that and the weak reference, or the other thing, then award the answer



来源:https://stackoverflow.com/questions/14677913/how-do-i-fix-this-android-memory-leak-involving-threads

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!