9

I have a C# application consisting of a Pivot with multiple Pivotitems. The normal Pivotitems unload properly and do not leak memory. On two of the items though, I have Drawingsurfaces on which I use Monogame to render 3d models. Upon the unloading and loading of their pivots I am trying to completely destroy and then completely recreate the "Game" instances (mainly because Monogame does not allow you to draw to two surfaces at the moment and because they use a lot of memory and there is not enough for both of them).

My problem comes in that when I dispose the Xamlgame that is created upon loading it does not release all the memory it used. This means that every time I recreate the Xamlgame it just starts using more and more memory until there is no more left. Therefore, I would like to know if there is any C# way to completely dispose of all memory that was taken into use upon loading of an object.

Any Monogame specific way would also be appreciated. At the moment I am first disposing of my vertex and index buffer, then I clear my vertex and index lists, I then dispose of my Basiceffect and my Graphicsdevicemanager, I then call dispose on the "game" itself and finally I make the variable that contains the "game" equal to null.

PS. If you have ever done this in XNA then you might also be able to help me because the syntax is basically the same.

EDIT (Might be MonoGame bug):

I have now managed to clean all buffers etc. up properly. There is still a memory leak on my BasicEffect though. I have tried disposing it and making it null but no matter what it just keeps using more and more memory every time I reload my pivot.

Gerharddc
  • 3,921
  • 8
  • 45
  • 83
  • If you're disposing of all the `IDisposable` resources then does [`GC.Collect`](http://msdn.microsoft.com/en-us/library/System.GC.Collect.aspx) not work? – Dustin Kingen Jul 07 '13 at 06:51
  • I am calling it but it doe not seem to have an effect – Gerharddc Jul 07 '13 at 06:53
  • are you sure you are disposing all the connections and items? can you share your code? – No Idea For Name Jul 07 '13 at 06:54
  • Okay then see [Force garbage collection of arrays, C#](http://stackoverflow.com/questions/1104352/force-garbage-collection-of-arrays-c-sharp). You probably need to preallocate the large chunks of memory to help the GC optimize the large object heap. – Dustin Kingen Jul 07 '13 at 06:55
  • 1
    It's possible that something internal to MonoGame is hanging on to the memory. Can you run a memory profiler over your code to find it? In particular, static references can often be the root of the evil. Take a look at the implementation of the Game class, it has an internal static reference to itself. https://github.com/mono/MonoGame/blob/develop/MonoGame.Framework/Game.cs – craftworkgames Jul 07 '13 at 10:25
  • @craftworkgames It might even be a more simple and serious bug in MonoGame - it could simply be leaking unmanaged resources (not implementing `IDisposable` and a finalizer correctly). Would not surprise me. – Andrew Russell Jul 07 '13 at 10:40
  • As mentioned in my edit to problem seems to be with BasicEffect because if I do not use it my memory doesn't leak. I have looked at the code for BasicEffect and it seems that there is no implementation for Dispose, should this be so? – Gerharddc Jul 07 '13 at 11:02
  • You should probably report this as a bug to the MonoGame team and link back to this question for reference. – craftworkgames Jul 09 '13 at 02:17

3 Answers3

8

First you'll need to set the value to null so it is no longer in use:

 XamlGame = null

Then you can Activate the garbage collector:

 GC.Collect();
 GC.WaitForPendingFinalizers();

If it does not dispose than either the XamlGame object is not null or a reference to it is still being held by another object.

Bear in mind that if XamlGame is inheriting from the Game class you won't be able to dispose it as it contain the running execution loop that keeps the entire game application alive. If you disposed it the application would crash and terminate.

ChargerIIC
  • 1,620
  • 1
  • 33
  • 47
  • Should probably note that most people shouldn't do this unless you have an extreme edge case such as this. Garbage collection is expensive and will freeze your program while it's collecting – Epic Speedy Aug 14 '21 at 17:39
7

use garbage collector and wait to finalize it.

            GC.Collect();
            GC.WaitForPendingFinalizers();
Mostafa Soghandi
  • 1,524
  • 1
  • 12
  • 20
-3

Apparently MonoGame simply does not support being created more than once in a game and will leak memory if this operation is performed. The somewhat more complicated is to use only one game instance and change the panel that it is drawing to.

Gerharddc
  • 3,921
  • 8
  • 45
  • 83