8

所以我发现,随着我MAT不断创造多个ThreadssurfaceCreate

不过,我认为我需要这些线程,但是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

泄漏

编辑:从那以后,我发现依赖于surfaceDestroyed我的线程的破坏是不可靠的。我现在从不同的方法调用适当的线程破坏调用,触发onPause

4

3 回答 3

4

您应该使用 Wea​​kReference 来引用您线程中的职业。这样,当没有更多对职业的硬引用时,引用将被清除。

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

于 2013-02-07T08:22:37.777 回答
1

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

您可以参考这个问题,了解更多详情

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    boolean retry = true;
    mThread.setRunning(false);
    while (retry) {
        try {
            mThread.join();
            retry = false;
        } catch (InterruptedException e) {
        }
    }
}
于 2013-02-09T02:28:44.193 回答
1

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

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

这也与答案WeakReferenceSurfaceDestroyed答案结合在一起。稍后我将对其进行测试,并确定是否只是删除了那一行,还是那一行与弱引用的组合,或其他事情,然后授予答案

于 2013-02-10T06:26:31.227 回答