Search code examples
c#memory-managementdisposexna-4.0

XNA 4.0 GameStateManagement Screens Not Freeing Memory


I'm using GameStateManagement and I'm having an issue with memory in my game. I have each segment of the game as a different screen. I have a screen for the logo, a screen for the main title, and so on. I think I've been managing the screens wrong but I've been having trouble finding information to my problem.

When this logo screen moves on to the title menu screen it doesn't seem to free up the memory resources of this logo screen and I seem to be having that issue with all of my screens and the memory starts stacking up quite a bit. Am I doing the UnloadContent right? Am I needing to call Dispose() on my textures and such under UnloadContent? Am I removing the screen correctly? Any thoughts on what I'm not doing right?

Here is my logo screen:

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);
        }
    }
}

Solution

  • ContentManager "owns" all of the resources that it loads. You cannot unload them yourself. You can only unload them with ContentManager.Unload - which unloads everything that that particular manager had loaded. (More details.)

    Therefore, if you want to load and unload resources on a per-screen basis, you have to create an instance of ContentManager for each screen.