我有一个Windows窗体应用程序,其中单击某些按钮可以从第二个窗体创建对象。在用户关闭此第二个表单时,不会释放此表单使用的内存(根据任务管理器)。
我尝试在主代码中的退出按钮this.dispose()
,this.close()
上使用form2 = null
,并在处置之前尝试通过代码清除此表单中的所有控件。这些都没有用,每次用户单击按钮时,应用程序的内存使用量都会增加,前一个实例使用的内存不会被释放。
我应该用什么来解决这个问题?
答案 0 :(得分:18)
调用Dispose
不会清理对象使用的内存。 Dispose
用于运行用户定义的代码,用于释放未自动释放的资源 - 如文件句柄,网络句柄,数据库连接等。
可能的罪魁祸首可能是第二种形式将事件附加到其外部的对象(可能是第一种形式?),而且从不解除它们。
如果您在第二个表单中有任何事件,请在OnClose覆盖中取消它们 - 这将使第二个表单符合垃圾回收的条件。
注意,.NET垃圾收集器非常难以预测,它可能会在清理所有符合收集条件的旧实例之前创建一个对象的几个实例。一种确定的方法(不依赖于内存分析器)是在终结器中放置一个断点:
public class MyForm : Form {
~MyForm() {
//breakpoint here
}
}
如果调用终结器然后这个类没问题,如果没有,你仍然有泄漏。你也可以给GC一个“踢” - 但仅用于故障排除 - 不要将此代码留在生产中 - 通过启动GC:
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
将上面的代码放在关闭后运行的某个位置并处理第二个表单。您应该在MyForm
终结器中点击断点。
答案 1 :(得分:3)
Dispose
不是用于释放内存 - 公共语言运行库的垃圾收集器负责处理内存。 Dispose用于释放其他(非内存)稀缺资源,如数据库连接和文件句柄。
一般来说,您不必担心.NET应用程序中的内存消耗,因为框架会为您执行此操作。如果你需要更好地控制内存消耗,你应该使用提供该控件的语言进行开发,比如C ++。
答案 2 :(得分:0)
听起来仍在使用内存,因为垃圾收集器尚未回收废弃的对象。尝试使用GC.Collect()静态方法强制进行垃圾回收。注意性能问题,因为这通常会使程序暂停,直到完成为止。
GC.Collect();
答案 3 :(得分:0)
不要调用Dispose()方法,调用 - >>>>>处置(真实)而你会很惊讶。它实际上释放了内存,你可能会在任务管理器中观察到效果。