memory leaks - Fugas de memoria de la cámara AForge
memory-leaks camera (3)
Estoy desarrollando una aplicación en C # y desarrollé una biblioteca que hace algunas cosas con Aforge
cámaras Aforge
. Uno de los puntos es simplemente capturar imágenes de lo que está delante de la Web Cam y mostrarlas en un PictureBox
específico para hacerlo:
camera.NewFrame += NewFrame;
private void NewFrame(object sender, NewFrameEventArgs args)
{
Bitmap newFrame = new Bitmap(args.Frame);
args.Frame.Dispose();
PictureBox.FromBitmapImage(newFrame);
newFrame.Dispose();
newFrame = null;
}
Lo que hago aquí, obtengo cada cuadro y lo pinto en el PictureBox
.
Mi duda es:
En algunas computadoras, esta forma de pintar produce una fuga de memoria realmente alta. La configuración de la cámara es: 640x480 , y si es más alta, la pérdida de memoria aumenta.
Configuracion de Computadora:
Intel i5: pérdida de memoria a 500 MB
Intel i7: SIN pérdida de memoria.
Doble coeur (no tan potente): No hay tanta pérdida de memoria.
EDITAR:
public static void FromBitmapImage(this Image image, Bitmap bitmap)
{
BitmapImage bitmapImage = new BitmapImage();
using (MemoryStream memoryStream = new MemoryStream())
{
bitmap.Save(memoryStream, ImageFormat.Bmp);
memoryStream.Position = 0;
bitmapImage.BeginInit();
bitmapImage.StreamSource = memoryStream;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
}
image.Source = bitmapImage;
bitmapImage = null;
}
No entiendo por qué tengo pérdida de memoria en algunas computadoras y otras no ... ¿Alguna sugerencia, por favor?
NOTA: Las pérdidas de memoria solo ocurren en el modo de lanzamiento en Visual Studio 2010, pero no en la depuración.
NOTA 2: Creo que el problema viene con FromBimapImage
, porque probé una aplicación de WindowsForms
lugar de una de WPF
y sin pérdida de memoria ...
AForge posee los bytes de la imagen, debes hacer tu propia copia profunda . Pasar el marco al constructor Bitmap no es suficiente. Si el marco no puede eliminar correctamente el mapa de bits porque tiene una referencia, hay una fuga.
Prueba con esto:
private void NewFrame(object sender, NewFrameEventArgs args)
{
Bitmap newFrame = AForge.Imaging.Image.Clone(args.Frame);
PictureBox.FromBitmapImage(newFrame);
newFrame.Dispose();
}
Esto funciona para mí
if (pictureBox1.Image != null) {
pictureBox1.Image.Dispose();
}
Bitmap bitmap = eventArgs.Frame.Clone() as Bitmap;
pictureBox1.Image = bitmap;
La eliminación de la imagen del cuadro de imagen justo antes de asignar uno nuevo funcionó para evitar la pérdida de memoria, pero arrojó errores cuando redimensioné el cuadro de imagen. Probablemente el problema se deba a eliminar la imagen demasiado pronto. Lo que funcionó para mí fue mantener las imágenes viejas en una cola y eliminarlas con un retraso de 5 imágenes. Esto le dará a la caja de imágenes tiempo suficiente para ponerse al día.
private Queue<Image> _oldImages = new Queue<Image>();
...
if (pictureBox1.Image != null)
{
_oldImages.Enqueue(pictureBox1.Image);
if (_oldImages.Count > 5)
{
var oldest = _oldImages.Dequeue();
oldest.Dispose();
}
}