How to reduce the amount of memory used by consecutive Graphics.DrawImage()

I'm working on building an application that displays one of three images in a list images on a picture box every 3 seconds, and the way I did this is by loading one of the images directly into the picture box using

drawing.Image = Image.FromFile(images[1]);

Then I used the Graphics class to draw the other 2 images.

void PictureBox_Paint_alarm(object sender, PaintEventArgs e)
        {
            if (rotationCounter > images.Count-1)
                rotationCounter = 0;
            if (rotationCounter != 1)
                e.Graphics.DrawImage(Image.FromFile(images[rotationCounter]), new RectangleF(0, 0, drawing.Size.Width, drawing.Size.Height));
        }

The rotationCounter increments by 1 every 3 seconds and the application function as intended. However, I have noticed that the program is consuming more memory as time goes by, until it reaches 5 Gigabytes then it goes back to 400 KB, the images have an average size of 450 KB.

The problem is that I'm going to be deploying this program on a system that only has 2 GB of RAM

2 answers

  • answered 2020-03-31 09:14 Damien_The_Unbeliever

    You have an images array (or something very like it) that is currently storing file names. Instead of doing that, load the images once and have an array of those instead of file names. That way you're not constantly reloading the images from file.

    That also means you don't keep creating very (resource) expensive Image objects. Those things implement IDisposable and so are meant to be disposed when no longer required. You're instead just letting them sit around until they're Garbage Collected:

    until it reaches 5 Gigabytes then it goes back to 400 KB, the images have an average size of 450 KB.

    Which is exactly what you're describing here.

    The problem is that I'm going to be deploying this program on a system that only has 2 GB of RAM

    And that wouldn't be a problem because a) programs don't allocate physical memory and b) the Garbage Collector would kick in earlier when memory pressure sets in.

  • answered 2020-03-31 09:42 D J

    You can use GC.Collect(); to use Garbage Collector.

    Also if you have declared objects, you can use DeleteObject() to delete it after use.

    This link might be useful: Deleting & Releasing GDI objects