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 Bitmap
s 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...