**Background info**

I've developed a desktop application with Windows Form (C#) for scanning, previewing and saving images.
The app behaviour while scanning is the following:

1. Scan *n* images
2. Get a Bitmap for each image and store it in a temporary file
3. Show resized thumbnails as a preview

---

**Image memory management: Compressible images**

For managing the memory usage, I've created a CompressibleImage class which encapsulates a Bitmap file and reads/writes images file on a FileStream. When an image is not longer required by the application, it is written into a file stream. When the app requires an image (ie. user double-click on a thumbnail), a Bitmap file is created from the stream. Here are the main **CompressibleImage's** methods:

```
/// Gets the uncompressed image. If the image is compressed, it will be uncompressed
public Image GetDecompressedImage()
    {
        if (decompressedImage == null)
        {
            // Read Bitmap from file stream
            stream.Seek(0, SeekOrigin.Begin);
            decompressedImage = new Bitmap(stream);
        }
        return decompressedImage;
    }

/// Clears the uncompressed image, leaving the compressed one in memory.
public void ClearDecompressedImage()
{
    // If Bitmap file exists, write it to file and dispose it
    if (decompressedImage != null)
    {
        if (stream == null)
        {
            stream = new FileStream(FileStreamPath, FileMode.Create);    
        }
        decompressedImage.Save(stream, format);
        // The Dispose() call does not solve the issue
        // decompressedImage.Dispose();
        decompressedImage = null;
        }
    }

    /// <summary>
    /// Class destructor. It disposes the decompressed image (if this exists), 
    /// closes the stream and delete the temporary file associated.
    /// </summary>
    ~CompressibleImage()
    {
        if (decompressedImage != null)
        {
            decompressedImage.Dispose();
        }
        if(stream != null)
        {
            stream.Close();
            File.Delete(stream.Name);
            stream.Dispose();
        }
    }

```

---

**Application level**

The application uses CompressibleImage to create image files mainly during the scan method and the saving process.
The scan method works fine and it basically:

1. Acquire Bitmap from scanner
2. Create a CompressibleImage from the scanned Bitmap
3. Write the Bitmap to the file stream

The save method works fine on my machine and its behaviour is as follows:
 1. For each CompressibleImage decompress (read & build) Bitmap from stream
 2. Save image
 3. Compress image

Here is the **save** method:

```
private void saveImage_button_Click(object sender, EventArgs e)
    {
        if (Directory.Exists(OutputPath) ==  false && File.Exists(OutputPath) == false)
        {
            Directory.CreateDirectory(OutputPath);
        }

        ListView.CheckedListViewItemCollection checkedItems = listView1.CheckedItems;
        if(checkedItems.Count > 0)
        {
            for (int i = 0; i < checkedItems.Count; ++i)
            {
                int index = checkedItems[i].Index;
                Bitmap image = (Bitmap)compressibleImageList.ElementAt(index).GetDecompressedImage();
                try
                {
                    image.Save(OutputPath + index.ToString() +
                               Module.PNG_FORMAT, ImageFormat.Png);
                    compressibleImageList.ElementAt(index).ClearDecompressedImage();
                    progressForm.Increment();
                    image = null;
                }
                catch (Exception ex) {
                    ...
                }
            }
        }
    }

```

---

**Issue Description**

In my machine the application works fine. There is no memory leak and the **scan** and **save** methods do their job smoothly and with a reasonable memory usage (scanning 100 papersheets with less than < 140MB pick).

The problem is, when I tried to test the application on other machines, the Garbage collector doesn't free up the memory, causing a **MemoryException** during the execution of both methods and when the amount of image is reasonably high (>40). The exception is thrown inside the **CompressibleImage.GetDecompressedImage()** method when I attempt to decompress (read) an image:

```
decompressedImage = new Bitmap(stream);

```

Although I known that the GC clean the memory randomly, in this case it seems like it doesn't even run and in fact the memory is released only when I close the application. 

It is possible such different behaviour on similar machines?

**System's info**

Here are some info about the testing environments. Both machines have:

* Processor: Intel i7 2.30GHz
* RAM: 8GB
* Type: 64-bit
* OS: Windows 7 Pro SP 1