我将以下代码作为游戏的一部分:
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,更新纹理比我遇到的任何其他方法要快得多,以使纹理变为空白)
答案 0 :(得分:2)
根据您的Game
配置以及其他许多因素,例如一切运行速度等等,Update
和Draw
并非完全同步,而是无法保证以下列方式运行:
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