Search code examples
c#windows-phone-8xnagarbage-collectiondispose

Creating an object many times and destroy it: is it good what I do?


I have a function that loads gameobjects (in particular it generates its cache on a texture, in order to use it later)

// This function is called during the game loading screen (with progress bar)
public void Loader()
{
    for (int i = 0; i < game_objects_.Count; ++i) // ~250
    {
         game_objects_[i] = new GameObject();
         game_objects_[i].DrawCache(spriteBatch);
    }
    GC.Collect();
}

// Inside GameObject class
...
public GameObject()
{
    // ...
    // GameObject is composed of 3 (different) objects, to be drawn in one texture. 
    piece1_ = new Piece1();
    piece2_ = new Piece2();
    piece3_ = new Piece3(); 
}

public void DrawCache(spriteBatch s)
{
    // On RenderTarget2D cache_
    piece1_.Draw(s);
    piece2_.Draw(s);
    piece3_.Draw(s);

    // Due to the fact that I won't use anymore these 3 objects, but just the Whole "cache_"
    // I can "destroy" them
    piece1_.Dispose();
    piece2_.Dispose();
    piece3_.Dispose();
}

Am I doing it right? I'm asking this because AFTER the loading screen (at the end of Loader function), I still get some "little random freeze" in the game for about 2 seconds, so I thought that maybe the GC is doing something although the function has finished, or maybe I have a wrong undertanding of how Dispose() is being used.


Solution

    • Avoid GC.Collect(); unless you are really sure of what you are doing : C# is not C++, you do not control the lifetime of an object, and in particular you do not control the moment when memory will be freed. Calling GC.Collect() usually creates more issues, and fixes none.

    Unless your program consumed almost all available memory (you should check how much memory, there is no reason why the GC would make your application freeze.

    Notes:

    • Inside GameObject, you should put pieces in a List and iterate over it : code will be easier to maintain and to read.
    • Consider using statment for automating (and enforcing) calls to Dispose()

    Example:

    public interface IPiece : IDisposable
    {
        void Draw(spriteBatch s);
    }
    
    // ...
    
    public void DrawCache(spriteBatch s)
    {
        // On RenderTarget2D cache_
        foreach(var piece in this.pieces)     
        {
          using(piece)
          {
             piece_.Draw(s);
          }
        }
    }