XNA WP7 Texture memory and ContentManager

Posted by jlongstreet on Game Development See other posts from Game Development or by jlongstreet
Published on 2011-12-08T23:15:19Z Indexed on 2012/06/11 22:48 UTC
Read the original article Hit count: 222

I'm trying to get my WP7 XNA game's memory under control and under the 90MB limit for submission. One target I identified was UI textures, especially fullscreen ones, that would never get unloaded.

So I moved UI texture loads to their own ContentManager so I can unload them. However, this doesn't seem to affect the value of Microsoft.Phone.Info.DeviceExtendedProperties.GetValue("ApplicationCurrentMemoryUsage"), so it doesn't look like the memory is actually being released.

Example: splash screens. In Game.LoadContent():

Application.Instance.SetContentManager("UI");  // set the current content manager

for (int i = 0; i < mSplashTextures.Length; ++i)
{
    // load the splash textures
    mSplashTextures[i] = Application.Instance.Content.Load<Texture2D>(msSplashTextureNames[i]); 
}

// set the content manager back to the global one
Application.Instance.SetContentManager("Global");

When the initial load is done and the title screen starts, I do:

Application.Instance.GetContentManager("UI").Unload();

The three textures take about 6.5 MB of memory.

Before unloading the UI ContentManager, I see that ApplicationCurrentMemoryUsage is at 34.29 MB. After unloading the ContentManager (and doing a full GC.Collect()), it's still at 34.29 MB. But after that, I load another fullscreen texture (for the title screen background) and memory usage still doesn't change.

Could it be keeping the memory for these textures allocated and reusing it?

edit: very simple test:

    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch(GraphicsDevice);

        PrintMemUsage("Before texture load: ");
        // TODO: use this.Content to load your game content here
        red = this.Content.Load<Texture2D>("Untitled");
        PrintMemUsage("After texture load: ");
    }

    private void PrintMemUsage(string tag)
    {
        Debug.WriteLine(tag + Microsoft.Phone.Info.DeviceExtendedProperties.GetValue("ApplicationCurrentMemoryUsage"));
    }

    protected override void Update(GameTime gameTime)
    {
        // Allows the game to exit
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();

        // TODO: Add your update logic here
        if (count++ == 100)
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
            PrintMemUsage("Before CM unload: ");
            this.Content.Dispose();
            GC.Collect();
            GC.WaitForPendingFinalizers();
            PrintMemUsage("After CM unload: ");
            red = null;
            spriteBatch.Dispose();
            GC.Collect();
            GC.WaitForPendingFinalizers();
            PrintMemUsage("After SpriteBatch Dispose(): ");
        }

        base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        // TODO: Add your drawing code here
        if (red != null)
        {
            spriteBatch.Begin();
            spriteBatch.Draw(red, new Vector2(0,0), Color.White);
            spriteBatch.End();
        }

        base.Draw(gameTime);
    }

This prints something like (it changes every time):

Before texture load: 7532544
After texture load: 10727424
Before CM unload: 9875456
After CM unload: 9953280
After SpriteBatch Dispose(): 9953280

© Game Development or respective owner

Related posts about XNA

Related posts about windows-phone-7