【问题标题】:Gif image in windows form application causing memory leakageWindows窗体应用程序中的Gif图像导致内存泄漏
【发布时间】:2016-11-02 12:57:58
【问题描述】:

我在 Windows 形式的 PictureBox 中使用了 gif 图像。 当我运行我的应用程序时,应用程序的内存使用量不断上升。

代码是:

pictureBox2.Image = Image.FromFile("image.gif");

我怎样才能摆脱这种情况? 谢谢!

【问题讨论】:

  • 至少放堆栈跟踪。
  • 如果内存已满,GAC会清空。否则 if(pictureBox2.Image != null) {pictureBox2.Image.Dispose()}
  • 不完全确定 picturebox.image 的机制是什么。但可能是垃圾收集器认为没有必要释放内存,所以它一直在上升
  • 我在任务管理器中观察到内存使用情况
  • 其他一切都很好,但问题是当我查看任务管理器时,我的应用程序内存使用量正在增加。

标签: c# winforms gif


【解决方案1】:

如果您查看documentation of the image class,您会发现该类实现了System.IDisposable

这意味着该类的设计者希望鼓励您积极确保在您不再需要图像时调用 Dispose()。这样做的原因是因为类的设计者使用了一些稀缺资源,如果在不再需要对象时立即释放它们会很好。

在你的情况下,稀缺的来源是(除其他外)内存。

当然,垃圾收集器会确保对象被释放,但如果你把它留给垃圾收集器,这不会尽快完成。通常你不确定垃圾收集器何时会清理内存。

因此,如果您正在高速加载图像,那么在您加载下一张图像之前,您的旧图像很有可能没有被垃圾收集。

为了确保对象尽快被释放,您可以使用类似的方法:

Image myImage = ...
DoSomeImageHandling (myImage)
// myImage not needed anymore:
myImage.Dispose();
// load a new myImage:
myImage = ... // or: myImage = null;

这样做的问题是,如果 DoSomeImageHandling 抛出异常,则不会调用 Dispose。 using 语句会处理它:

using (Image myImage = ...)
{
   DoSomeImageHandling (myImage);
}

现在,如果 using 块被留下,无论出于何种原因,无论是正常留下,还是因异常或返回后或其他任何原因,都会调用 myImage.Dispose()。

顺便说一句,在您的情况下,稀缺的来源不仅是内存,只要您不按照下面的代码显示图像,文件也会被锁定

string fileName = ...
Image myImage = new Image(fileName);
DoSomething(myImage);
// my image and the file not needed anymore: delete the file:

myImage = null; // forgot to call Dispose()
File.Delete(fileName);
// quite often IOException, because the file is still in use

正确的代码是:

string fileName = ...
using (Image myImage = new Image(fileName))
{
    DoSomething(myImage);
}
// Dispose has been called automatically, the file can be deleted
File.Delete(fileName);

【讨论】:

    猜你喜欢
    • 2011-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-08
    • 2019-10-21
    • 2018-03-29
    相关资源
    最近更新 更多