我开始了一个项目,其概念是在整个游戏中连续重用相同的texture2d对象,定期重新加载新纹理。随着时间的推移,这被证明是一个坏主意,因为我遇到了:System.OutOfMemoryException
bool loadImages(string image)
{
System.Diagnostics.Debug.WriteLine("beginning loading textures " + image);
try
{
//image_a = null;
//image_o = null;
//image_o.Dispose();
//image_a.Dispose();
image_o = Content.Load<Texture2D>("images/"+image);
image_a = Content.Load<Texture2D>("images/" + image+"_a");
return true;
}
catch
{
System.Diagnostics.Debug.WriteLine("cannot load textures " + image);
image_a.Dispose();
image_o.Dispose();
}
return false; //make sure the caller loads the subsequent image
}
我猜测 XNA 在每次加载新内容时都会保留过去的纹理,因此我重写了程序,改为保存一个游戏对象列表,每个对象都有自己的texture2d 对象。浏览列表后,我将处理前一个列表项的纹理对象,并将下一个列表项的纹理加载到其纹理对象。该列表在整个游戏中只会遍历一次,我只是定期移动到下一个纹理集,并且我只会挑选 2 个纹理进行加载,因此理论上内存中始终只需要 2 个纹理。我仍然遇到内存错误。就好像我根本无法依靠 dispose 方法及时从内存中释放纹理一样。
我加载的纹理均不超过 125KB,我正在为 Windows Phone 7 构建此纹理
删除我不再需要的纹理的最佳方法是什么?参考代码:我应该创建新的texture2d对象,交换它们,然后处理原始对象吗?
好的,首先介绍一下背景:ContentManager
缓存加载的对象。有更详细的描述here (or here)。但基本上每个ContentManager
owns它加载的所有内容。你不应该打电话Dispose
关于该内容。清理它的唯一方法是卸载缓存中的所有内容ContentManager.Unload
(or Dispose
).
我猜您遇到的问题是您尝试过Load
您之前调用过的纹理Dispose
打开 - 然后尝试使用该已处理的纹理。
虽然我想你也可能会耗尽内存,因为ContentManager
正在存储所有这些(空的,已处理的)Texture2D
对象,防止垃圾收集器回收它们(请参阅这个答案).
所以,如果你想走这条路,你需要修改缓存策略ContentManager
。如何执行此操作在中进行了解释这篇博文。但基本上你继承自ContentManager
, 覆盖Load
,并致电ReadAsset
当您想要从内容文件创建资产的新实例时。
最简单的方法是完全禁用缓存,该博客文章中有一个具体的示例。然后,您可以简单地手动管理内容管理器加载的所有内容的生命周期(即:调用Dispose
自己做吧)。
如果您想要更复杂的东西,也许看看我提出的设计这个答案,在 GameDev 网站上。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)