Lenator
Lenator

Reputation: 13

System.OutOfMemoryException: Out Of Memory

I'm making a game which uses Graphics to draw random pictures from the folder. Here It Is:

This is for a game on C#

public static int cookiecount;
public static Random random = new Random();
public static string[] files = Directory.GetFiles(Application.StartupPath, "*.png");
public static Image im;

public static void Draw(System.Drawing.Graphics g, int x, int y)
{
    try
    {
        im = Image.FromFile(files[random.Next(0, files.Count())]);

        g.DrawImage(im, x, y, 40, 40);
    }
    catch(Exception ee) {
        MessageBox.Show("Error! " +ee.Message + " " + ee.Source + " " + ee.HelpLink,
            "Oh No", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }

    cookiecount++;
}

It outputs an error that says:

System.OutOfMemoryException: Out Of Memory

Upvotes: 0

Views: 870

Answers (1)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112392

As others have said, you have a memory leak as you are not disposing the images. Note: usually memory of unused objects gets freed up automatically in C#, but images are special, as they are COM-objects, i.e. non-.NET-objects.

Instead of loading the images over and over, load them once. Since the same images are used during the whole game, you don't need to dispose them.

public static int cookiecount;
public static Random random = new Random();
public static Image[] images;

// Call this once at program start.
public static LoadImages()
{
    string[] files = Directory.GetFiles(Application.StartupPath, "*.png");
    images = new Image[files.Length];
    for (int i = 0; i < files.Length; i++) {
        images[i] = Image.FromFile(files[i]);
    }
}

public static void Draw(System.Drawing.Graphics g, int x, int y)
{
    int index = random.Next(0, images.Length);
    g.DrawImage(images[index], x, y, 40, 40);

    cookiecount++;
}

For arrays, use the Length property instead of calling the Count() extension method. It is more efficient.

Also, the exception handling should be moved to LoadImages(). For sake of simplicity, I did not show it here.

Upvotes: 1

Related Questions