我有8个大内存块(每个内存块28mb)。它们存储在非托管(本机)代码中。我想将它们转储到文件中。但是,在我将它们转储之后,它们不会被释放,并且我有230mb的繁忙内存,无法继续运行我的应用程序。进一步抛出OutOfMemory。
这是我的转储代码:
//* Dump input images
for (int i = 0; i < frames.Length; i++)
{
StorageFile file = await localFolder.CreateFileAsync(
string.Format("FRAME_{0}.yuv", i),
CreationCollisionOption.ReplaceExisting);
using (var stream = await file.OpenStreamForWriteAsync())
{
byte[] image = SwapHeap.copyFromHeap(frames[i].ImagePtr, (int)frames[i].Width * (int)frames[i].Height * 3 / 2);
await stream.WriteAsync(image, 0, image.Length);
await stream.FlushAsync();
image = null;
}
}
...
System.GC.Collect();
以及从
byte[]
指针获取int
的本机代码:Array<uint8>^ SwapHeap::copyFromHeap(const int ptr, int length)
{
Array<uint8>^ res = ref new Array<uint8>(length);
memcpy(res->Data, (byte*)ptr, length);
return res;
}
我使用
free((byte*)ptr);
释放了本机代码中的内存,没关系。但是我不明白,为什么不发布byte
数组?附言我可以使用本机代码转储数据,但我想了解GC的工作原理(我已经阅读过msdn)。
最佳答案
看起来像Stream
类中的问题。据我从不同的测试可以了解,它锁定了byte
数组,该数组被写入流中。并且它没有在using
块之外关闭或释放。
如果使用FileIO
而不是Stream
并将转储代码更改为:
// Dump input images
for (int i = 0; i < frames.Length; i++)
{
StorageFile file = await Windows.Storage.KnownFolders.PicturesLibrary.CreateFileAsync(
string.Format("FRAME_{0}.yuv", i), CreationCollisionOption.ReplaceExisting);
byte[] image = SwapHeap.copyFromHeap(frames[i].ImagePtr, (int)frames[i].Width * (int)frames[i].Height * 3 / 2);
await FileIO.WriteBytesAsync(file, image);
image = null;
file = null;
}
一切都很好。
关于c# - Windows Phone 8.1内存问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32112314/