Image.RotateFlip memory leak: /

Although I have been programming for about 11 years (mostly VB6, the last 6 months of C #), this is the first time I really asked a question :) I found all my answers from interwebz, but I can’t solve this question myself. Your site is one of the most useful places where I have the best answers!

I will show the code that I am using (excerpt from what is appropriate). The problem is that when using the RotateFlip method, the memory quickly increases to ~ 200 M, and then is collected through the GC after a while. The main method that calls it iterates about 30 times per second, so performance is paramount here. I tried using the transform matrix, but sometimes it fails and shows the image without reflection. The application itself is based on using a webcam, hiding the preview, removing the callback and showing it in the image window. Then it overlays the if rectangle from another class. This is the reason for using the callback window rather than the preview.

Class Capture.cs:

internal Bitmap LiveImage; int ISampleGrabberCB.BufferCB(double bufferSize, IntPtr pBuffer, int bufferLen) { LiveImage = new Bitmap(_width, _height, _stride, PixelFormat.Format24bppRgb, pBuffer); if (ExpImg) // local bool, used rarely when the picture saving is triggered { LiveImage.RotateFlip(RotateFlipType.RotateNoneFlipY); var a = LiveImage.Clone(new Rectangle(Currect.Left, Currect.Top, Currect.Width, Currect.Height), LiveImage.PixelFormat); using (a) a.Save("ocr.bmp", ImageFormat.Bmp); } else // dmnit, rotateflip leaks like h*ll but matrix transform doesn't sometimes flip :S { LiveImage.RotateFlip(RotateFlipType.RotateNoneFlipY); /*using (var g = Graphics.FromImage(LiveImage)) { g.Transform = _mtx; g.DrawImage(LiveImage, 0, 0); }*/ } GC.Collect(); // gotta use it with rotateflip, otherwise it gets crazy big, like ~200M :O return 0; } } 

In the main form, I have an event that updates the image in the frame:

 private void SetPic() { pctCamera.Image = _cam.LiveImage; _cam.PicIsFree = false; } 

Since I need to get an image in the main form, which is in another class, then I realized that the most logical is the set Bitmap, which is updated in every frame of the callback. The reason I don’t want to use matrix transformation is that it is slower, and sometimes I can’t flip the image at that speed, and the frequency of this behavior is very different from different PCs with different hardware capabilities and processor speed, as well as with fast frame rate This shows a frequency of 30 frames per second with a frequency of 1.2 GHz.

So can you help me figure it out? I don't actually use it in the current version, I use the transformed matrix transformation because I feel bad for using GC.Collect: (

Thanks!

+6
source share
3 answers
 pctCamera.Image = _cam.LiveImage; 

The heavy use of memory, as you observe, is a sure sign that you missed the opportunity to call Dispose () somewhere, allowing unmanaged resources (mainly in memory) used by the bitmap to be freed sooner rather than letting the garbage collector do this. The ordered operator is one such case; you are not deleting the old image referenced by the image window. Fix:

 if (pctCamera.Image != null) pctCamera.Image.Dispose(); pctCamera.Image = _cam.LiveImage; 
+5
source

You can rewrite your code as follows:

 internal Bitmap LiveImage; int ISampleGrabberCB.BufferCB(double bufferSize, IntPtr pBuffer, int bufferLen) { using (LiveImage = new Bitmap(_width, _height, _stride, PixelFormat.Format24bppRgb, pBuffer)) { LiveImage.RotateFlip(RotateFlipType.RotateNoneFlipY); if (ExpImg) // local bool, used rarely when the picture saving is triggered { var a = LiveImage.Clone(new Rectangle(Currect.Left, Currect.Top, Currect.Width, Currect.Height), LiveImage.PixelFormat); using (a) a.Save("ocr.bmp", ImageFormat.Bmp); } } return 0; } 

Bitmap is an Image class, and implements IDispose . When you create Bitmap every time, I suggest using the using statement to automatically free resources.

+1
source

GC.Collect exists for this situation. Data collection is ONLY a way to free it, and when creating HUGE bitmap images, this is the way to go. Does GC.Collect really slow down?

In addition, you should keep the number of raster copies as low as possible.

-2
source

Source: https://habr.com/ru/post/892218/


All Articles