3.5 Memory Issues. ContentManager.Unload() not working properly?

I finally made the switch to 3.5.1 a few days ago (I’ve been using 3.4 for a long time) and all seemed well until I started noticing performance issues and took a look at my Resource Monitor. Nearly across the board my game’s memory usage has doubled from what it was (Edit: This is actually a result of what I explain below, not an issue with more memory being used for an asset between 3.5 and 3.4), but that isn’t the oddest part.

When I exit the game to the main menu I unload all content, which would normally drop the memory usage quite a bit because I only have a single menu loaded as opposed to a map, enemies, characters, etc. Instead I see no change in memory usage. What’s worse is that starting the game again nearly doubles my memory usage. Repeating this step will continuously increase my memory usage by roughly the same amount each time, as if it’s loading all of the content again, but never actually freeing up the memory when I call Content.Unload();

To test this further I loaded my game up and started running through different maps. Each map loads all necessary content on entering and unloads it all on exit. Every time I change maps it only increases memory usage. Content.Unload() doesn’t seem to do reduce it.

Am I missing something obvious here, or is there a bug? The only changes I made were switching from VS2010 -> VS2015, .Net 4.0 -> .Net 4.5 and Monogame 3.4 -> Monogame 3.5.

I’m just offering a guess here, but have you tried .Dispose() instead?

I haven’t because it would be a fairly large change in my engine to switch every Content.Unload() to Dispose() and I want to determine what the issue is before doing that. I might do a small test tomorrow to see if that fixes it though.

Regardless, it’s weird that this is happening. I’m going to try switching back to an older version of Monogame tomorrow morning to see what happens, as well as trying the development branch build.

My you can do a project-wide search-and-replace, and it will only take a second?

Oh definitely, it would be a fast change. There would be a ton of testing involved to make sure everything works correctly afterward and it seems like a band-aid fix as opposed to finding the cause of this new problem.

Also, won’t Dispose() make it so I can’t load the same asset in the future? The reference to the asset in the ContentManager remains, so reloading it doesn’t do anything because it’s still flagged as “isDisposed”. I could be wrong here, I have pretty limited experience with Dispose().

I don’t know about an is-disposed flag… That sounds like something that would be garbage collected, doesn’t it? So you don’t fill up memory with disposed content ID’s.

But I dont know the technicalities of how these things work. I’m just pretty sure I have used Dispose() to free up memory, but that I have not used Unload()…

You should never manually dispose content managed by a ContentManager. Dispose should be used for unmanaged resources. If your unloaded objects are not garbage collected you probably still have references to them.

1 Like

I can confirm now that this is definitely an issue with Monogame 3.5+. I’ve tried 3.6 as well on the development branch and I had the same issue. Changing maps (unloading content) and exiting to the main menu (unloading all game content) didn’t effect Memory Usage in the Resource Monitor on Windows, nor did it effect the Process Memory in the Diagnostic Tools of VS2015. (Other than an increase in memory as more content is loaded)

I switched back to Monogame 3.4 and the game began behaving as it normally would, where changing from a large map to a smaller one reduces memory usage, and exiting to the main menu reduces it significantly, because only the menu textures are loaded.

I made zero code changes during these tests. I only installed different versions of Monogame.

One change that has happened is the loading now uses a buffer pool to help reduce memory allocation during load by reusing buffers. There may be some issue with this system. That is the only thing I can think of that has changed in that area.

There was a bug fix merged for the buffer pool two days ago. Was your development branch test done after that? If it still happens, we’ll have a look further into it.

Unfortunately, yes. I did the tests this morning. If there’s anything I can do to help pinpoint this let me know.

I’m not sure if it matters at all, but I’m only loading Textures and a single Effect file, no sounds at all.

You can try using the memory profiler to find out where the new allocations are coming from. I’ll try this tonight as well to see if I can replicate the behaviour.

Oh, I should have mentioned that before! I used the memory profiler last night and found that the extra usage was in fact the same content being doubled. For example:

  1. Load Game -> 10 Objects loaded into memory (5kb, 10kb, 20b, etc)
  2. Exit to Main Menu -> (Should clear all of these)
  3. Load Game again -> 20 Objects loaded, I can tell they’re duplicates because every pair of two has nearly exactly the same amount of memory usage. (5kb, 5kb, 10kb, 11kb, 20kb, 19kb…)

It was actually more complicated than just having 10 objects loaded, but that was essentially what was happening. If you can’t replicate it I will switch back to 3.6 tomorrow and take some screenshots of the profiler’s results, as well as some other stuff.

What was odd was any Main Menu/Game Load cycles after the second one would actually cause the Process Memory to spike a bit then fall back down right as I took a snapshot. I’m not sure what was going on there.

@KonajuGames Did you ever get a chance to check this out?