我有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/

10-09 18:16
查看更多