If I execute the code below, OutOfMemoryException occurs at either the line
using (Bitmap bitmap1 = new Bitmap(FrameToFilePath(interval.Start - 1)))
or the line
using (Bitmap bitmap2 = new Bitmap(FrameToFilePath(interval.End + 1)))
when the inner for statement executed about 1000 times.
However, I don't know why OutOfMemoryException occurs. I think I have written enough using to dispose Bitmap objects. Where does the memory leak occurs?
class Program
{
static void Main(string[] args)
{
// Some code to initialize List<Interval> intervals
Parallel.ForEach(intervals, interval =>
{
using (Bitmap bitmap1 = new Bitmap(FrameToFilePath(interval.Start - 1)))
using (Bitmap bitmap2 = new Bitmap(FrameToFilePath(interval.End + 1)))
{
for (int i = interval.Start; i <= interval.End; i++)
{
ColorMatrix colorMatrix = new ColorMatrix(); // Identity matrix
colorMatrix.Matrix33 = (i - interval.Start + 1F) / (interval.Span + 1F); // Alpha
using (ImageAttributes imageAttributes = new ImageAttributes())
using (Bitmap intermediate = new Bitmap(bitmap1.Width, bitmap1.Height, PixelFormat.Format32bppArgb))
using (Graphics graphics = Graphics.FromImage(intermediate))
{
imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
graphics.DrawImage(bitmap1, 0, 0);
graphics.DrawImage(bitmap2, new Rectangle(0, 0, intermediate.Width, intermediate.Height), 0, 0, bitmap2.Width, bitmap2.Height, GraphicsUnit.Pixel, imageAttributes);
intermediate.Save(FrameToFilePath(i), ImageFormat.Png);
}
}
}
});
}
static string FrameToFilePath(int frame)
{
return string.Format(@"C:\(some path)\frames\frame-{0:00000}.png", frame);
}
}
class Interval
{
public int Start { get; set; }
public int End { get; set; }
public int Span { get { return End - Start + 1; } }
}
EDIT: OK. Maybe it's because Parallel.ForEach spawns tasks before other tasks ended, so that more and more tasks are started but Bitmaps were not GCed since the tasks were not ended. Well, if this is the case, how to fix it to avoid OutofMemoryException? I am not sure if this is the case yet though...