-2

I'm creating a streaming app that get byte from server continuity with this code:

while (true)
            {
                byte[] buffer = await _client.GetStreamOneCameraAsync();
                if (buffer.Length == 0) continue;
                SoftwareBitmap softwareBitmap = SoftwareBitmap.CreateCopyFromBuffer(buffer.AsBuffer(), BitmapPixelFormat.Gray8, 1280, 960);
                //buffer = null; if I put this here, it will solve the memory leak
                //GC.Collect();
                if (softwareBitmap.BitmapPixelFormat != BitmapPixelFormat.Bgra8 ||
                    softwareBitmap.BitmapAlphaMode == BitmapAlphaMode.Straight)
                {
                    softwareBitmap = SoftwareBitmap.Convert(softwareBitmap, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
                }
                _imageSource = new SoftwareBitmapSource();
                await _imageSource.SetBitmapAsync(softwareBitmap);

                // Set the source of the Image control
                image_Preview.Source = _imageSource;

            }

So my question is: Is it enough to clear all the memory that byte[] taken? My next task is display that image to the UI. So maybe it will make the memory leak?

UPDATE: Thanks you guys for supporting. I just realize that my memory leak problem was came out when I convert that buffer to image and display it into the UI and not dispose it. it doesn't due to the byte[]

UPDATE 2: I updated full of my code. Please help me to check where make the memory leak?

Bui Quang Huy
  • 1,784
  • 2
  • 17
  • 50
  • 3
    Possible duplicate of [How do i explicitly clear the byte\[\]](https://stackoverflow.com/questions/5892732/how-do-i-explicitly-clear-the-byte) – Owen Pauling Aug 03 '17 at 10:44
  • 1
    Maybe it's just me, but I don't see the point in clearing if your next iteration will overwrite `buffer` anyway. I suspect you are trying to solve a problem that is rather caused by `// Do some stuff` than your `byte[] buffer`. – Filburt Aug 03 '17 at 10:45
  • 3
    There are very few times when an explicit call to `GC.Collect()` is necessary, I'd argue that calling within your loop would create more of a performance impact than potentially not unallocating your byte array. As you are redefining `buffer` on each loop iteration, let the GC do it's job and manage the heap for you. – Chris Pickford Aug 03 '17 at 10:48
  • I have had occasional memory problems with allocating multiple large buffers in very quick succession which have been resolved by calling GC.Collect() - I believe the problems were related to memory fragmentation rather than being out of memory - see this [link](https://stackoverflow.com/questions/5240860/what-causes-memory-fragmentation-in-net). It may be appropriate to put any disposable objects (like SoftwareBitmap) in a using statement & move the GC-Collect() call to either the start or the end of the while loop. – PaulF Aug 03 '17 at 11:04
  • The memory old byte[] taken wasn't gone. I keep tracking the processing memory chart in VS 2017 and see it increase very fast. So I think it necessary to set buffer = null here. – Bui Quang Huy Aug 03 '17 at 15:23
  • @BuiQuangHuy No, nulling out the variable doesn't do anything. It's eligible for collection even without that, so long as nothing else references the array. – Servy Aug 03 '17 at 15:35
  • Please check my update in the question – Bui Quang Huy Aug 03 '17 at 15:50

1 Answers1

3

Actually I believe there is no point in setting buffer to null here.
Once your loop resets he buffer is going to be redefined anyways, and the old memory will be cleared by the automatic GarbageCollector.

If you really spot a memory leak you can try forcing garbage collection, but in this case that shouldn't be necessary. (Although it could depend on how your method goes on after the // Do some stuff.)

References:

Whats so wrong about GC.Collect()?
When is it acceptable to call GC.Collect?

Edit:

I believe placing the SoftwareBitmap in a using clause to guarantee that the resources are freed, should solve your memory leak.

using (SoftwareBitmap softwareBitmap = SoftwareBitmap.CreateCopyFromBuffer(buffer.AsBuffer(), BitmapPixelFormat.Gray8, 1280, 960);)
{
    buffer = null;
    GC.Collect();
    if (softwareBitmap.BitmapPixelFormat != BitmapPixelFormat.Bgra8 ||
        softwareBitmap.BitmapAlphaMode == BitmapAlphaMode.Straight)
    {
        softwareBitmap = SoftwareBitmap.Convert(softwareBitmap, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
    }
    _imageSource = new SoftwareBitmapSource();
    await _imageSource.SetBitmapAsync(softwareBitmap);

    // Set the source of the Image control
    image_Preview.Source = _imageSource;
}
Ian H.
  • 3,840
  • 4
  • 30
  • 60