首页 > 解决方案 > 补救措施卡在最终确定而无需手动调用 GC

问题描述

我们在 C# 应用程序中有一组特定的操作,这些操作会导致 RAM 继续增长,直到表单关闭。此表单长期存在,一些用户不会整天关闭此表单。

基本上,FormfrmRelationalSearch调用 FormfrmCombinedSearch来搜索一个人,当 Form关闭时,FormfrmCombinedSearch会将该人返回给 Form 。形式是这里长寿的形式,而形式似乎是引起问题的形式。frmRelationalSearchfrmCombinedSearchfrmRelationalSearchfrmCombinedSearch

出于测试目的,我手动添加了GC.Collect()每个GC.WaitForPendingFinalizers()人的搜索周期,以查看它是否真的是内存泄漏。我已经意识到表单frmCombinedSearch确实被 GC 收集了,并且可能只是因为它在终结器队列中而存活了很长时间。我没有得到的是如何在不手动调用的情况下解决不断增长的 RAM 使用问题,GC.Collect()GC.WaitForPendingFinalizers()我们的代码中,这是一种不好的做法。

我已经使用 dotMemory 和 ANTS 内存分析器确认了这一点。

我该如何处理?在这种情况下手动调用 GC 是否可以接受?

这是现在的代码:

private void btnSearch_Click(object sender, EventArgs e)
{
    // Without these three lines, the RAM will continue to grow until
    // this form (frmRelationalSearch) is closed.

    // GC.Collect();
    // GC.WaitForPendingFinalizers();
    // GC.Collect();

    frmCombinedSearch frm = new frmCombinedSearch();
    try
    {
        // Custom code which just shows the form in the current tab
        frm.ShowInTab(this.ParentTabPage);
    }
    catch (Exception ex)
    {
        this.ShowException(ex);
    }
}

在两个分析器中,frmCombinedSearch由于终结器队列而被保留。

编辑ShowInTab()是非阻塞的,所以我不能使用using语句来处理它,因为它只会在它创建后立即被处理。

标签: c#winformsmemory-leaksgarbage-collection

解决方案


WinForms 需要关闭或处置(链接)。我建议使用using.

private void btnSearch_Click(object sender, EventArgs e)
{
    using (frmCombinedSearch frm = new frmCombinedSearch())
    {
        try
        {
            // Custom code which just shows the form in the current tab
            frm.ShowInTab(this.ParentTabPage);
        }
        catch (Exception ex)
        {
            this.ShowException(ex);
        }
    }
}

推荐阅读