【问题标题】:XNA 4.0 GameStateManagement Screens Not Freeing MemoryXNA 4.0 GameStateManagement 屏幕未释放内存
【发布时间】:2012-10-25 05:08:05
【问题描述】:

我正在使用 GameStateManagement,但我在游戏中遇到了内存问题。我将游戏的每个部分作为不同的屏幕。我有一个用于徽标的屏幕,一个用于主标题的屏幕,等等。我认为我一直在错误地管理屏幕,但我一直无法找到有关我的问题的信息。

当这个标志屏幕移动到标题菜单屏幕时,它似乎并没有释放这个标志屏幕的内存资源,我的所有屏幕似乎都有这个问题,内存开始堆积很多少量。我在做 UnloadContent 对吗?我是否需要在 UnloadContent 下对我的纹理等调用 Dispose()?我是否正确移除了屏幕?对我做的不对有什么想法吗?

这是我的徽标屏幕:

namespace Tower_Defense
{
    class Logo : GameScreen
    {
        Tower_Defense curGame;
        GraphicsDeviceManager graphics;
        AudioManager audioManager;
        Texture2D logoTexture;
        int gamecycles;

        public Logo(Tower_Defense game, GraphicsDeviceManager g, AudioManager am)
        {
            curGame = game;
            audioManager = am;
            graphics = g;
            EnabledGestures = GestureType.Tap;
        }

        public override void LoadContent()
        {
            base.LoadContent();

            logoTexture = Load<Texture2D>("Textures/Backgrounds/logo");

            gamecycles = 0;
        }

        public override void UnloadContent()
        {
            base.UnloadContent();
        }

        public override void Draw(GameTime gameTime)
        {
            ScreenManager.SpriteBatch.Begin();

            ScreenManager.SpriteBatch.Draw(logoTexture, Vector2.Zero, Color.White);

            ScreenManager.SpriteBatch.End();
        }

        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            gamecycles++;

            if (gamecycles >= 60)
            {
                ScreenManager.AddScreen(new TitleScreen(curGame, graphics, audioManager, false), null);
                this.UnloadContent();
                ScreenManager.RemoveScreen(this);
            }

            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
        }
    }
}

【问题讨论】:

  • 你如何测量内存使用情况?

标签: c# memory-management dispose xna-4.0


【解决方案1】:

ContentManager“拥有”它加载的所有资源。您不能自己卸载它们。您只能使用ContentManager.Unload 卸载它们 - 这会卸载该特定经理已加载的所有内容。 (Moredetails.)

因此,如果您想在每个屏幕上加载和卸载资源,您必须为每个屏幕创建一个ContentManager 的实例。

【讨论】:

  • 这是有道理的,但我遇到了一些问题。创建一个新的 ContentManager 似乎需要一个 IServiceProvider 构造函数,所以我想也许我可以将相同的 ContentManager 传递给每个新屏幕,然后在进入每个新屏幕之前继续清除它。 base.UnloadContent() 有点让我困惑。我试着这样做,以为我会使用相同的内容管理器,但在加载下一个屏幕时它给了我一个空纹理。这个 ContentManager 的东西让我很困惑。
  • @Ted:您可以从Game.Services 获得IServiceProvider(这是与Game.Content 相同的服务提供商)。 base 只是指GameScreen(“在我的父类上调用此方法”)。您应该能够右键单击它并按“转到定义”以查看它的作用(如果您有 GameScreen 的来源)。
  • 感谢您的帮助,我会从 Game.Services 获取它,明天再试一次您所说的,时间还早。
  • 决定我不想等待尝试,似乎我已经收到您的建议,即每个屏幕都有自己的内容管理器可以工作。这大大减少了我的内存使用量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多