【发布时间】:2018-01-10 21:58:52
【问题描述】:
我正在创建一个流式应用程序,它使用以下代码从服务器连续性中获取字节:
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;
}
所以我的问题是:是否足以清除 byte[] 占用的所有内存? 我的下一个任务是将该图像显示到 UI。那么也许它会导致内存泄漏?
更新: 谢谢你们的支持。我只是意识到,当我将该缓冲区转换为图像并将其显示到 UI 中而不是处理它时,我的内存泄漏问题就出现了。这不是由于字节[]
更新 2:我更新了全部代码。请帮我检查一下内存泄漏在哪里?
【问题讨论】:
-
也许只有我一个人,但如果你的下一次迭代会覆盖
buffer,我看不出有什么意义。我怀疑您正在尝试解决由// Do some stuff而不是您的byte[] buffer引起的问题。 -
很少有需要显式调用
GC.Collect()的情况,我认为在循环中调用会比可能不取消分配字节数组产生更大的性能影响。当您在每次循环迭代时重新定义buffer时,让 GC 完成它的工作并为您管理堆。 -
我偶尔会遇到快速连续分配多个大缓冲区的内存问题,这些问题已通过调用 GC.Collect() 解决 - 我认为问题与内存碎片有关,而不是内存不足- 看到这个link。将任何一次性对象(如 SoftwareBitmap)放在 using 语句中并将 GC-Collect() 调用移动到 while 循环的开头或结尾可能是合适的。
-
占用的内存旧字节[]并未消失。我一直在跟踪 VS 2017 中的处理内存图表,发现它增长得非常快。所以我觉得这里有必要设置buffer = null。
标签: c# .net garbage-collection