我正在计算机上保存当前图像的屏幕截图:
Rectangle bounds = Screen.GetBounds(Point.Empty);
using (var bitmap = new Bitmap(bounds.Width, bounds.Height))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
}
using (var mss = new MemoryStream())
{
bitmap.Save(mss,ImageFormat.Gif);
}
}
内存漏洞就在这段代码中:
bitmap.Save(mss,ImageFormat.Gif);
我不应该使用using
处理我正在使用的所有内容吗?
为什么在拍摄大量照片时内存仍然非常高,并且内存未被释放?
谢谢!
答案 0 :(得分:3)
我的问题是,即使在MemoryStream
上调用byte[]
,Dispose
也未释放其内部byte[]
。在MemoryStream
超出范围并由GC收集之前,MemoryStream
不会被释放。
This blog post详细说明问题的原因,并提供a working solution.它对我有用,我怀疑你遇到了同样的问题。本质上,它将底层Dispose()
包装在一个实现相同接口的类型中,但在调用byte[]
时将流引用设置为null。由于没有其他对象应该具有对内部流的实时引用,因此GC允许GC进入并清理它。
此外,由于内部{{1}}可能会在大对象堆上分配,导致多次分配后出现碎片,这个问题更加复杂。
答案 1 :(得分:2)
您可以尝试使用BufferManager,它将为您管理Byte []。
// declare the BufferManager somewhere. Check thread safety!
BufferManager bm = BufferManager.CreateBufferManager(qqq, yyy);
// wrap your current code to use the buffer manager
Rectangle bounds = Screen.GetBounds(Point.Empty);
using (var bitmap = new Bitmap(bounds.Width, bounds.Height))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
}
byte[] buffer = bm.TakeBuffer(yyy);
try
{
using (MemoryStream stream = new MemoryStream(buffer))
{
bitmap.Save(mss,ImageFormat.Gif);
}
}
finally
{
bm.ReturnBuffer(buffer);
}
}