卡住的补救措施无需手动调用GC即可完成

时间:2019-01-03 01:10:48

标签: c# winforms memory-leaks garbage-collection

我们的C#应用​​程序中有一组特定的操作,这些操作导致RAM继续增长,直到窗体关闭。该表单存在很长一段时间,有些用户不会在一整天都关闭该表单。

基本上,表单frmRelationalSearch调用表单frmCombinedSearch来搜索人,表单frmCombinedSearch会在表单frmRelationalSearch时将其返回表单frmCombinedSearch。关闭。形式frmRelationalSearch是这里的长期存在形式,而形式frmCombinedSearch似乎是引起问题的形式。

出于测试目的,我在每个人搜索周期中手动添加了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语句来处理它,因为它会在创建后立即被处理。

2 个答案:

答案 0 :(得分:0)

WinForms需要关闭或处置(link)。我建议使用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);
        }
    }
}

答案 1 :(得分:0)

frmCombinedSearchfrmRelationalSearch可以丢弃吗?如果是,则可以实现一个use,因此一旦关闭便将其收集起来。

类似以下内容:

using(frmCombinedSearch frm = new frmCombinedSearch()){
    try {
       frm.ShowInTab(this.ParentTabPage); }
    catch(Exception ex) {
       this.ShowException(ex); } }