【问题标题】:How do I load pictures in Zune XNA without running out of memory?如何在 Zune XNA 中加载图片而不会耗尽内存?
【发布时间】:2010-11-06 17:53:16
【问题描述】:

我正在编写一个 XNA 程序来显示 Zune 上特定相册中的图片。问题是,如果我从相册中的所有图片加载纹理,程序就会耗尽内存。一旦用户移动到下一张图片,我尝试一张一张地加载并在上一张图片纹理上调用 Dispose。这可行,但是一旦处理后我无法从上一张图片中取回纹理,因此用户无法在不重新启动程序的情况下查看过去的图片!

【问题讨论】:

  • 为什么不直接重新加载它,使用相同的逻辑?
  • 嗯,我必须通过一系列相册来检索所有图片,然后在将它们呈现给用户之前对它们进行排序。每次用户按下后退按钮查看过去的图片时,这样做会很疯狂。肯定有更好的解决方案吗?

标签: xna image texture2d zune


【解决方案1】:

不要在相册中存储每个项目的纹理句柄。相反,请使用您在用户浏览相册时根据需要处置和加载的单个程序级句柄。

【讨论】:

  • 是的,这就是我正在做的事情。我只有一个纹理句柄在任何时候引用一张图片纹理。但是,一旦您从图片访问纹理,即使我为手柄分配不同的纹理,纹理也不会消失。它似乎被缓存在某个地方。如果我在纹理上调用 Dispose,我无法从图片中取回纹理。每次我调用 GetTexture 时,它​​都会一直返回 null。
  • 你能发布一些代码吗?确定是纹理的问题? IE。它是否保持了在您加载下一个文件时未清除的文件锁定,然后阻止您重新加载上一个文件?
  • 感谢您的帮助!我实际上已经更改了代码,因为现在必须将图片附加到 XNA 项目并编译为 XNB 文件。它可以工作,因为我现在可以使用 ContentManagers 加载和卸载我的图片。然而,这不是一个好的解决方案,因为如果我需要添加、删除或更改图片,我必须重新编译和部署整个程序!!我现在没有时间,但是周末我会写一个小程序来重新创建问题并发布代码。
【解决方案2】:

我建议您只对所有数据进行一次处理,并存储文件名(因此您只需对所有层次结构/排序进行一次)。然后只在需要时加载图片(正是上一篇文章所建议的)。

这个方法的问题是 Content.Load(string) 会加载你的纹理,但是如果你丢失了所有指向纹理的指针,ContentManager 会将纹理保存在内存中,这样如果你再次加载它就会立即加载。有一个方法 Content.Unload() 将删除这些缓存的项目,请参阅:

关于这个话题的论坛讨论:
http://forums.xna.com/forums/p/25978/141761.aspx
肖恩哈格里夫斯解释它:
http://blogs.msdn.com/shawnhar/archive/2006/09/06/743437.aspx

我实现这一点的方式是在每次停止使用图片时调用 unload,或者如果您想要更快的加载(这取决于用户更改图片的频率,如果他们真的要浏览图片每次都快速卸载是个坏主意)尝试捕获内存不足的异常,然后只调用 unload。

【讨论】:

  • 感谢您的帮助!是的,我通常会为每个纹理使用单独的 ContentManager,这样我就可以在必要时卸载它。但是,Zune 图片 API 不使用也不公开任何 ContentManager 来让我控制加载和卸载。它只有一种称为 GetTexture 的方法。它不使用正常的 Content.Load 模式!这就是为什么我如此沮丧! :-(
  • 啊,我没有意识到它在 zune 上有很大的不同。稍微阅读一下 MSDN(这是一个完整的猜测),您是否可以不只是在图片上调用 dispose(不是纹理,而是您调用 GetTexture 的图片),这应该释放图片正在使用的所有非托管资源(包括它的质地)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-05
  • 2020-11-20
  • 1970-01-01
  • 2018-10-17
  • 2021-02-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多