2013-02-16 65 views
3

我创建了一个动态下载并保存多个大图像的数据透视表。 我首先使用webclient下载图像并将其写入磁盘。 比创建一个包含所有图像的图像列表数组。 基本思想是我只在需要时才加载图像。 说我的清单中有12张图像。每张幻灯片只显示1个图像。假设我们正在查看图片7.我继续为下一张幻灯片预加载图片6 & 8。OutOfMemory异常<BitmapImage> .SetSource()

1, 2, 3, 4, 5, [6, {7}, 8], 9, 10, 11, 12 

当用户通过幻灯片浏览时,我保持图像在“[]”之外预加载并卸载。

我用于预加载图像的代码:

BitmapImage bi = new BitmapImage(); 
bi.SetSource(GetStream(fileName); 
IMGSource = bi; // IMGSource<ImageSource> referenced by the xaml in Image Binding IMGSource. 

我用来卸载图像的代码:

IMGSource = null; 
GC.Collect(); // I force the program to Garbage collect since the image is really large. 

的问题是,一些图像被观看后(约9图像)。它会在该行中引发OutOfMemory异常:bi.SetSource

我检查了卸载功能都工作正常(它不释放内存调用收集后,和内存保持在一个稳定的点)

但它仍然抛出一个异常OutOfMemory。 我该怎么办?

编辑:
我才发现,其实内存通过幻灯片导航时继续上升
。通过调用:

Microsoft.Phone.Info.DeviceStatus.ApplicationCurrentMemoryUsage; 

它给喜欢回忆:

54.7 MB, 76.91 MB, 111.94 MB, 105 MB, 112.71 MB, 141.93 MB, 148.42 MB, Exception thrown 

但通过调用:

GC.GetTotalMemory(false); 

它显示只有约1.2~1.3 MB
发生了什么?不应该释放内存?

+0

请对[格式](http://meta.stackexchange.com/questions/22186/how-do-i-format-my-code-blocks)更敏感 – 2013-02-16 18:26:24

+0

对不起,我正在使用我的手机发布。它没有预览给我,我输入了四个空格代码。但事实证明它并不起作用:\ – user1510539 2013-02-16 18:29:28

+1

这可能不是泄漏的根源,但您应该确保在加载图片后关闭流:'使用(var stream = GetStream(fileName)){bi .SetSource(流); }' – 2013-02-16 19:20:48

回答

1

我最终设置了一个空的1x1透明GIF到图像源释放内存。

public static byte[] EMPTY_IMAGE = new byte[]{ 
    71, 73, 70, 56, 57, 97, 1, 0, 1 
    , 0, 128, 0, 0, 255, 255, 255 
    , 0, 0, 0, 33, 249, 4, 1, 0, 0 
    , 0, 0, 44, 0, 0, 0, 0, 1, 0, 1 
    , 0, 0, 2, 2, 68, 1, 0, 59 
}; 

,然后只用:

bi.SetSource(new System.IO.MemoryStream(MYCLASS.EMPTY_IMAGE)); 

而且记忆似乎释放正确。

+0

而不是1x1 GIF,您可以使用假图片并捕获异常:http://stackoverflow.com/a/13482619/869621 – 2013-02-17 09:14:41

+0

另外,如果您不介意,是否可以尝试将UriSource设置为null在这里:http://stackoverflow.com/a/13963747/869621,看看它的工作原理? – 2013-02-17 09:24:38

+0

我试图使用新的字节[] {0x0},但它给我一个执行。所以这就是我使用1x1 GIF的原因。 – user1510539 2013-02-17 09:29:39