如何修复涉及Threads的Android内存泄漏?

时间:2013-02-03 22:10:58

标签: android memory-leaks

所以我找到了MAT,我每隔Threads

继续创建多个surfaceCreate

我认为我需要这些线程,但是当用户浏览我的应用程序时,这种方法会导致ViewThread的多个实例,这是内存泄漏。

如何重新组织我的线程的创建和处理方式,以便不会发生这种情况,或者如何阻止泄漏的发生?

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

我打开并远离我游戏的Career活动五次,这就是MAT

上显示的内容

leak

编辑:我发现依赖于surfaceDestroyed来破坏我的线程是不可靠的。我现在从另一个方法调用适当的线程销毁调用,触发onPause

3 个答案:

答案 0 :(得分:4)

您应该使用WeakReference来引用线程中的职业生涯。这样,当没有对职业生涯的更多硬性引用时,将清除引用。

您可以通过右键单击职业并选择Path To GC Roots跟踪MAT中的所有引用,然后选择所有引用。这将显示保留在内存中的对象的路径。确保在完成活动后清除这些引用,或者使用WeakReferences让GC自动清除它们。

答案 1 :(得分:1)

surfaceDestroyed内,您应等待以确保线程在您返回之前停止。

您可以参考this question了解详情

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

答案 2 :(得分:1)

所以我通过评论一行来修复它:

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

这也与WeakReferenceSurfaceDestroyed答案相结合。 我稍后会对它进行测试并确定它是否仅仅删除了那一行,或者它与弱引用的组合,或者另一种情况,然后给出答案