我需要使用内存流,因为我从数据库加载图像。当我使用文件流时,只是为了比较,应用程序的占用空间与未压缩图像的1倍大小一致。但是如果我使用内存流,内存使用量更像是3倍。我使用了200MB的PNG图像(4张图像),应用程序占用了1GB的RAM。
有没有办法减少内存使用?
private BitmapImage readfromdsk(string s)
{
var photo2f = File.Open(s, FileMode.Open, FileAccess.Read);
byte[] b = null;
photo2f.Read(b=new byte[photo2f.Length], 0, (int)photo2f.Length);
var bitmapImage = new BitmapImage();
using (MemoryStream ms = new MemoryStream(b))
{
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.StreamSource = ms; //// lot of memory allocated on this line
bitmapImage.EndInit();
}
b = null;
photo2f.Dispose();
return bitmapImage;
}
字符串
2条答案
按热度按时间pzfprimi1#
这里发生的是
BitmapImage
正在创建它自己拥有和管理的像素的副本。在文件流版本中,它可以以小块(例如,一次4kb)。因此,在这个例子中,它将结束使用(4kb +未压缩位图大小)内存。
在您的内存流版本中,您首先将整个文件读入内存。所以它最终是(文件大小+未压缩位图大小)。
BitmapImage
不直接使用字节数组。它仍然一次“流”一个块。如果你想在阅读数据库时减少内存,你需要构建一个流类(实现
System.IO.Stream
),它每次从数据库读取一个块。最后要考虑的事情:这可能是也可能不是一个问题。GC将恢复字节数组使用的内存,因此内存使用的增加只是暂时的。
643ylb082#
正如在
.NET Memory issues loading ~40 images, memory not reclaimed, potentially due to LOH fragmentation
一个
MemoryStream
似乎保留了一个对你在构造时传递的字节数组的引用,即使在它被释放之后。这是一个问题,因为BitmapImage
也保留了对其StreamSource
的引用,因此原始输入字节数组永远不会被释放。为了避免这种情况,您可以使用一个额外的
BufferedStream
,它会在释放它的源流时释放对它的引用。字符串