Question

Je suis un Newby en C #. Je dois rafraîchir à plusieurs reprises une zone d'image graphique dans un thread de travail. L'image est acquise à partir d'un sondage de la caméra un pilote avec une méthode qui GetImage retrives l'image à afficher. Même si je le bitmap à l'aide allouer directive « utilisation » et appeler explicitement G.C, la mémoire semble jamais désallouée.

Le thread de travail est quelque chose comme ceci:

   while (true)
    {
        // request image with IR signal values (array of UInt16)
        image = axLVCam.GetImage(0);
        lut = axLVCam.GetLUT(1);
        DrawPicture(image, lut);
        //GC.Collect();

    }

Bien que la méthode de DrawPicture est quelque chose comme

   public void DrawPicture(object image, object lut)
{

  [...]

    // We have an image - cast it to proper type
    System.UInt16[,] im = image as System.UInt16[,];
    float[] lutTempConversion = lut as float[];

    int lngWidthIrImage = im.GetLength(0);
    int lngHeightIrImage = im.GetLength(1);

    using (Bitmap bmp = new Bitmap(lngWidthIrImage, lngHeightIrImage)) {

      [...many operation on bitmap pixel...]

        // Bitmap is ready - update image control

        //SetControlPropertyThreadSafe(tempTxtBox, "Text", string.Format("{0:0.#}", lutTempConversion[im[160, 100]]));

        //tempTxtBox.Text = string.Format("{0:00000}", im[160, 100]);
        //System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());
        pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());
    }
}

Les problèmes se pose avec la

  

pic.Image = System.Drawing.Image.FromHbitmap (bmp.GetHbitmap ());

En fait commentant cette ligne de code, travaille la collecte des ordures comme il le ferait. Mieux, le problème semble être avec

  

System.Drawing.Image.FromHbitmap (bmp.GetHbitmap ())

Des conseils pour résoudre cette fuite de mémoire?

Merci beaucoup!

Était-ce utile?

La solution

Image implémente IDisposable, vous devez donc appeler Dispose sur chaque instance Image que vous créez, quand il ne sera plus nécessaire. Vous pouvez essayer de remplacer cette ligne dans votre code:

pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());

Avec ceci:

if (pic.Image != null)
{
    pic.Image.Dispose();
}
pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());

disposera de l'image précédente (le cas échéant) avant que le nouveau est attribué.

Autres conseils

La chose est, vous faites un bitmap GDI de bmp avec GetHbitmap qui, selon msdn:

  

Vous êtes responsable d'appeler la   Procédé GDI DeleteObject pour libérer le   La mémoire utilisée par l'objet bitmap GDI.

Ensuite, la méthode de FromHbitmap fait une copie de l'image bitmap GDI; de sorte que vous pouvez libérer le bitmap GDI entrant à l'aide immédiatement la méthode DeleteObject GDI après la création de la nouvelle image.

Donc, fondamentalement, je voudrais ajouter:

[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);

...

IntPtr gdiBitmap = bmp.GetHbitmap();

// Release the copied GDI bitmap
if (pic.Image != null)
{
    pic.Image.Dispose();
}

pic.Image = System.Drawing.Image.FromHbitmap(gdiBitmap);

// Release the current GDI bitmap
DeleteObject(gdiBitmap);

Je ne suis pas sûr si vous avez besoin du bitmap GDI pour effectuer une sorte de transformation. Si vous ne vous ne pouvez pas affecter le bitmap à la propriété d'image de votre PictureBox, et ignorer l'ancienne solution:

// Since we're not using unmanaged resources anymore, explicitly disposing 
// the Image only results in more immediate garbage collection, there wouldn't 
// actually be a memory leak if you forget to dispose.
if (pic.Image != null)
{
    pic.Image.Dispose();
}

pic.Image = bmp;

Il existe plusieurs façons de libérer une image de pbox. Je recommande vivement la voie est que ne pas utiliser pbox.Image = Image.FromFile.... Si vous n'utilisez pas FileStream et que vous voulez le lire à partir du fichier de classe utilisation BitMap. Comme ceci:

Bitmap bmp = new Bitmap(fileName);
pbox.Image = bmp; // notice that we used bitmap class to initialize pbox.

... et vous voulez libérer le fichier image bmp.Dispose();
Maintenant, vous pouvez supprimer, déplacer ou tout ce que vous voulez dans le fichier.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top