1

我有一个很大的 winform 类,它从一个像这样的小人那里调用:

    void login()
    {           
        mainForm f1 = new mainForm();                
        f1.ShowDialog();
    }

登录后主窗体会占用大量内存(我在任务管理器中检查)。关闭主窗体后,程序返回登录窗体。在这一步我再次检查任务管理器,发现我的程序没有释放 mainForm 使用的内存。登录后,我的程序崩溃并显示“内存不足”错误。

我不得不说我测试了 f1.Dispose()、f1=null、GC.Collect() 和我发现的所有其他方法。

它只会在我关闭登录表单时释放内存(它是 Application.Run 中使用的起始类)

我想销毁 mainForm 实例(f1)和这个表单的所有资源,就像我关闭程序时一样。

4

3 回答 3

3

不太确定OOM与登录表单有什么关系。正如Taskmgr.exe 所报告的那样,关闭或处理表单会减少内存使用量肯定不是这种情况。

但你肯定做错了。对话框在 Winforms 中的处理方式不同,它不会像使用 Show() 显示的表单那样自动处理。因此,您必须在对话框关闭后检索用户在对话框中输入的任何内容,这在对话框被释放时将是危险的。所以你必须自己做。正确的模式是:

    using (mainForm f1 = new mainForm()) {
        if (f1.ShowDialog() == DialogResult.Ok) {
            // Retrieve data entered by user and do something with it
            //...
        }
    }

使用using语句可确保您检索对话结果后释放对话实例。

于 2012-07-08T14:58:02.967 回答
2

几个想法:

于 2012-07-08T14:15:22.203 回答
1

也许主窗体在显示时会创建对自身的引用,检查它分配的任何引用/委托/事件并确保它们在主窗体完成时未注册,或者将事件处理程序(即应用程序事件)移动到单独的类。

到目前为止,100% 的时间我都“发现了 .NET 内存泄漏”,但事实并非如此!处理所有一次性用品,注意你对保存引用的静态数据所做的事情,不要进行重复的事件订阅,并在可能的情况下整理它们。

使用 SOS,正如 mouters 所说,在运行 dispose 并调用 GC.Collect(3) 几次后检查 mainform 类上的 gcroots,一旦你跟踪引用的位置,你应该找到错误。

于 2012-07-08T14:34:32.880 回答