表单关闭时的可用内存

时间:2020-12-29 21:17:50

I have two forms "Main" and "Clients". Application starts with Main and it contains a button that opens the second one. But when I close Clients, Process Memory (Visual Studio diagnostic tools) don't reduce and if I open the form again it raises (like it creates another instance without destroying previous one). I've created the destructor method just to see if it's called but it didn't.

我有两种形式“主要”和“客户”。应用程序从Main开始,它包含一个打开第二个按钮的按钮。但是,当我关闭客户端时,进程内存(Visual Studio诊断工具)不会减少,如果我再次打开表单,它会引发(就像它创建另一个实例而不会破坏前一个实例)。我创建了析构函数方法,只是为了看它是否被调用,但它没有。

public partial class MainMenu : Form {
    public MainMenu() {
        InitializeComponent();
    }

    private void button2_Click(object sender, EventArgs e) {
        //Data obtained from API
        List<Client> clientList = new List<Client> {
            new Client(0, 0, "Ralph", "asd", "asd", "asd", "asd", "asd", "asd", "asd", "asd")
        };

        //I bind this list to BindingSource of Client form
        BindingListView<Client> cL = new BindingListView<Client>(clientList);

        //Client form
        BaseForm<Client> form = new BaseForm<Client>(new UI.Content.ClientContent(), cL, Measures.ClientsFormSize);            
        form.Show();
    }
}

This is for Client form:

这是客户表格:

public partial class BaseForm<T> : Form {
    public class SearchItem {
        private string name;
        private string value;

        public string Name { get => name; }
        public string Value { get => value; }

        public SearchItem(string name, string value) {
            this.name = name;
            this.value = value;
        }

        public override string ToString() {
            return name;
        }
    }

    private UserStatus currentStatus;
    private Forms.BaseContent formContent;
    private List<ICustomControl> controlList;
    private int registers;

    internal BindingListView<T> Data {
        get => (BindingListView<T>)formContent.BindSource.List;
        set {
            formContent.BindSource.DataSource = value;
        }
    }

    internal BaseForm(Forms.BaseContent content, BindingListView<T> data, Size formSize) : this(content, data) {
        Size = formSize;
    }

    internal BaseForm(Forms.BaseContent content, BindingListView<T> data) : this(content) {
        Data = data;
        registers = Data.Count;
        Last();
    }

    internal BaseForm(Forms.BaseContent formContent) : this() {
        this.formContent = formContent;
        FitContentToPanel();
    }

    internal BaseForm() {
        InitializeComponent();
        currentStatus = UserStatus.View;
    }
}

I think this is due to form is never assigned to null and for that the GC won't take it. I've tried doing a static member and override the OnClosingForm to prevent closing but I think there are a better way.

我认为这是因为表单永远不会被赋值为null,因此GC不会接受它。我试过做一个静态成员并覆盖OnClosingForm以防止关闭,但我认为有更好的方法。

2 个解决方案

#1


1  

GC is not supposed to reclaim memory right away after you close a child form.

关闭子表单后,GC不应立即回收内存。

Try forcing collection by calling .Collect() 2-3 times before you open the child form and after the form is closed. If the memory is not released that would mean you've got a memory leak.

在打开子表单之前和表单关闭之后,通过调用.Collect()2-3次尝试强制收集。如果没有释放内存,那就意味着你有内存泄漏。

GC.Collect();   
GC.Collect();   
GC.Collect();   

To clarify, I suggest forcing GC to collect memory only as a quick and dirty way to check the memory in Debug time. Do not check-in such code, nor include it into release version.

为了澄清,我建议强制GC只收集内存作为在调试时检查内存的快速而肮脏的方法。不要签入此类代码,也不要将其包含在发布版本中。

#2


1  

Use this syntax for faster memory disposal:

使用此语法可以更快地处理内存:

using (YourForm f = new YourForm())
{
    // ...
    f.ShowDialog();
}

#1


1  

GC is not supposed to reclaim memory right away after you close a child form.

关闭子表单后,GC不应立即回收内存。

Try forcing collection by calling .Collect() 2-3 times before you open the child form and after the form is closed. If the memory is not released that would mean you've got a memory leak.

在打开子表单之前和表单关闭之后,通过调用.Collect()2-3次尝试强制收集。如果没有释放内存,那就意味着你有内存泄漏。

GC.Collect();   
GC.Collect();   
GC.Collect();   

To clarify, I suggest forcing GC to collect memory only as a quick and dirty way to check the memory in Debug time. Do not check-in such code, nor include it into release version.

为了澄清,我建议强制GC只收集内存作为在调试时检查内存的快速而肮脏的方法。不要签入此类代码,也不要将其包含在发布版本中。

#2


1  

Use this syntax for faster memory disposal:

使用此语法可以更快地处理内存:

using (YourForm f = new YourForm())
{
    // ...
    f.ShowDialog();
}