Windows Phone 8.1内存问题

3

我有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();

同时提供了从 int 指针获取 byte[] 的本地代码:

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)。


https://dev59.com/pmQn5IYBdhLWcg3wETk5#17131389 - Hans Passant
1个回答

0

看起来是在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;
}

一切都很好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接