【问题标题】:IsolatedStorage causes Memory to run out隔离存储导致内存耗尽
【发布时间】:2011-05-06 20:06:08
【问题描述】:

嘿。 当用户单击这样的项目时,我正在从独立存储中读取图像:

using (IsolatedStorageFile currentIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{

    using (var img = currentIsolatedStorage.OpenFile(fileName, FileMode.Open))
    {

        byte[] buffer = new byte[img.Length];
        imgStream = new MemoryStream(buffer);
        //read the imagestream into the byte array
        int read;
        while ((read = img.Read(buffer, 0, buffer.Length)) > 0)
        {
            img.Write(buffer, 0, read);
        }

        img.Close();
    }


}

这很好用,但是如果我在两个图像之间来回单击,内存消耗会不断增加,然后内存不足。有没有更有效的方式从独立存储中读取图像?我可以在内存中缓存几张图片,但有数百个结果,最终还是会占用内存。有什么建议吗?

【问题讨论】:

  • 除非我遗漏了什么,否则您上面的代码实际上并没有对 imgStream 做任何事情
  • 抱歉,返回了imgStream。上面的代码在一个返回 MemoryStream 的方法中。

标签: c# memory-management windows-phone-7 isolatedstorage


【解决方案1】:

您是否会在某个时候处理MemoryStream?这是我能找到的唯一泄漏点。

另外,Stream 有一个 CopyTo() 方法。您的代码可以重写为:

using (IsolatedStorageFile currentIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
    using (var img = currentIsolatedStorage.OpenFile(fileName, FileMode.Open))
    {
        var imgStream = new MemoryStream(img.Length);

        img.CopyTo(imgStream);

        return imgStream;
    }
}

这将节省许多内存分配。

编辑:

对于 Windows Phone(未定义 CopyTo()),将 CopyTo() 方法替换为其代码:

using (IsolatedStorageFile currentIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
    using (var img = currentIsolatedStorage.OpenFile(fileName, FileMode.Open))
    {
        var imgStream = new MemoryStream(img.Length);

        var buffer = new byte[Math.Min(1024, img.Length)];
        int read;

        while ((read = img.Read(buffer, 0, buffer.Length)) != 0)
            imgStream.Write(buffer, 0, read);

        return imgStream;
    }
}

这里的主要区别是缓冲区设置得相对较小(1K)。此外,通过为MemoryStream 的构造函数提供图像的长度来添加优化。这使得MemoryStream pre-alloc 成为必要的空间。

【讨论】:

  • 我认为 Using 语句可以做到这一点。但是,我删除了 Using 语句并手动处置,但最终还是导致它崩溃。
  • 我认为您实际上在其他地方使用MemoryStream?用完后,需要丢弃。 using 确保在 using 块的末尾调用 Dispose()。你需要在那之前完成它。
  • 谢谢。 MemoryStream 返回给调用方法。似乎 Windows Phone 7 没有 CopyTo 方法,因为它没有出现在我的智能感知中。有替代方法吗?
  • 不,抱歉。一会儿,我会用另一种方法更新我的答案。
  • 你去。希望这会有所帮助。
猜你喜欢
  • 2012-12-09
  • 1970-01-01
  • 1970-01-01
  • 2019-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-02
  • 2011-04-23
相关资源
最近更新 更多