Я получаю кадры из OpenCV Emgu в C#, и через некоторое время у меня заканчивается память. Проблема исчезает, когда я вручную удаляю старый кадр. Эти швы происходят только тогда, когда я получаю кадры из Emgu. Если я получаю кадры из AForge, например, он очищается, как и ожидалось.Почему изображение не отображается GC
Поскольку я делаю копию данных в CopyToNewBPP и удаляю кадр из захвата, память в неуправляемом должна быть отпущена. И не должно быть ссылок на старый фрейм, когда я устанавливаю новое растровое изображение в окне изображения.
Вопрос в том, чего я не вижу в своем понимании.
private void button1_Click(object sender, EventArgs e)
{
Capture capture = new Capture("rtsp://192.168.0.89:554/live2.sdp");
Task t = new Task(() =>
{
DateTime last = DateTime.Now;
while (true)
{
var frame = capture.QueryFrame();
if (frame == null)
{
continue;
}
Bitmap bitmap = CopyToNewBPP((Bitmap)frame.Bitmap);
frame.Dispose();
pictureBox1.Invoke(new MethodInvoker(() =>
{
var old = pictureBox1.Image;
pictureBox1.Image = bitmap;
if (old != null)
{
old.Dispose(); // this should be done automatically by GC in my mind
}
}));
frame.Dispose();
}
});
t.Start();
}
public Bitmap CopyToNewBPP(Bitmap orig, PixelFormat format = PixelFormat.Format32bppRgb)
{
Bitmap clone = new Bitmap(orig.Width, orig.Height, format);
using (Graphics gr = Graphics.FromImage(clone))
{
gr.DrawImage(orig, new Rectangle(0, 0, clone.Width, clone.Height));
}
return clone;
}
Похоже, я сам это понял. Проблема в том, что я быстро получаю фреймы. Я заполняю память до того, как планируется запустить GC. Добавление GC.Collect(); в цикле будет сохраняться использование памяти, но будет использовать метод Dispose, поскольку это намного быстрее. – klundby