设置纹理时内存泄漏= new Texture2D(...)

时间:2013-04-17 00:34:43

标签: c# performance xna garbage-collection xna-4.0

我将以下代码作为游戏的一部分:

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.Black);

        spriteBatch.Begin();

        terrainSprite.Draw(spriteBatch);

        if (resourceMap.pixels.IsDisposed == false)
        {
            resources.Draw(spriteBatch, spriteFont);
        }

        spriteBatch.End();

        base.Draw(gameTime);

       //Disposes the texture here:
        resources.pixels.Dispose();
    }

    //In the resources class
    public void Update()
    {       
        //gD = graphics device
        pixels = new Texture2D(gD, 800, 353);

        //big update method
        //manipulate the pixels texture
    }

当我打开任务管理器并查看资源监视器时,'myGame.exe'的内存使用量持续上升约8 KB(我意识到这很小,但我的游戏拥有大量数据,因此保存我能做的每一点都很重要,而且它很快就会积累起来。这是在所有其他代码被注释掉之后,除了这里显示的内容。然后,当我注释掉代码:“pixels = new Texture2D(gD,800,353);”时,内存使用率保持不变。我也试过GC.Collect(),但没有骰子。

我还能做些什么来试图阻止它吗? (对不起,摆脱代码不是一个选择:p,更新纹理比我遇到的任何其他方法要快得多,以使纹理变为空白)

2 个答案:

答案 0 :(得分:2)

根据您的Game配置以及其他许多因素,例如一切运行速度等等,UpdateDraw并非完全同步,而是无法保证以下列方式运行:

Update
Draw
Update
Draw
Update
Draw
Update
Draw
....

因此,既然你是Dispose并在另一个中创建一个全新的,那么这样的事情肯定会发生:

Update: create new
Update: create new //PREVIOUS ONE LEAKED!
Draw: disposes only current
Update: create new
Update: create new //AGAIN LEAK
Draw: disposes only current
...

因此,不要以这种方式单独Dispose; Dispose每次创建新的一次,无论如何。

我还应该添加纹理,以及其他一些XNA类(声音和音乐,以及Effect,仅举几例)是非托管资源,这意味着GC会根本看不到它们。您必须在这些电话上致电Dispose

正如安德鲁在评论中指出的那样,避免这些陷阱的最佳方法是不要经常重新创建纹理 - 只需重复使用相同的纹理并根据需要修改它。

答案 1 :(得分:0)

垃圾收集器似乎没有完全处理Texture2D。

因此,当您停止使用它时(如在此处重复使用引用它的变量时,或在OnDestroy回调期间),则必须手动销毁纹理。在这里:

this.form=this.initForm(null) //<--an empty form
this.form=this.initForm(workout ) //<--a form with the data