secile / UsbCamera

C# source code for using usb camera and web camera in WinForms/WPF. With only single CSharp source code. No external library required.
MIT License
179 stars 55 forks source link

Memory leak #15

Closed Alexxx8289 closed 1 year ago

Alexxx8289 commented 1 year ago

Hi, I am testing your code and I noticed that every time you take a snapshot the memory increases. Does it happen to you too?

EugeneQilo commented 1 year ago

@Alexxx8289 I think it is just wrong implementation.. not memory leak... The SampleGrabberCallback is being attached on every click... each SampleGrabberCallback buffers memory, hence the memory increase...

Solution, attach SampleGrabberCallback only once.... Change this line GetBitmap = () => GetBitmapFromSampleGrabberBuffer(i_grabber, width, height, stride);

To

var sampler = new SampleGrabberCallback();
i_grabberCapture.SetCallback(sampler, 1);
GetBitmap = () => sampler.GetBitmap(width, height, stride);
secile commented 1 year ago

Hello, Alexxx8289. Thank you for your question. I think my library is not leaking memory.

This picture is memory usage while executing my SampleProject\UsbCameraForms. image

Amount of memory usage is about 80MB in first. As I continuously executing GetBitmap() function, memory usage is keeps increasing, and after increasing to 180MB, it suddenly drops to abount 80MB. It is because garbage collection was executed. and it is normal operation.

I think reason for the increased memory usage is that the Bitmap object has not been disposed expressly.

If you change the code from

button1.Click += (s, ev) => pictureBox2.Image = camera.GetBitmap();

to

// get bitmap.
button1.Click += (s, ev) =>
{
    var bmp = pictureBox2.Image;
    bmp?.Dispose();
    pictureBox2.Image = camera.GetBitmap();
};

you can surpress memory usage. image

secile commented 1 year ago

Hello, EugeneQilo. Thank you for your opnion.

You said that 'The SampleGrabberCallback is being attached on every click', but I think your opinion is not applies.

Are you saying that the line 'var sampler = new SampleGrabberCallback();' is executed every GetBitmap() call? It is not correct.

GetBitmapFromSampleGrabberCallback function returns function of getting bitmap from sample grabber. the line 'GetBitmap = GetBitmapFromSampleGrabberCallback(i_grabber, width, height, stride)' means that GetBitmap delegate is set to function of getting bitmap from sample grabber.

When GetBitmap function is executed, The line is executed as follows:

line code
[Form1.cs line54] pictureBox2.Image = camera.GetBitmap();
[UsbCamera.cs line408] sampler.GetBitmap(width, height, stride);
[UsbCamera.cs line356] GetBitmap function.