Is there a workaround for ToolStrip to not leak me

2019-09-08 16:22发布

问题:

I have a simple form (MainForm) that opens another form (SubForm) which has a ToolStrip on it.

There is nothing else on the called form. The calling form only has a button.

The memory of the form that is called is never reclaimed because there is an eventhandler for SystemEvents.UserPreferenceChanged. I read that this is an issue that got fixed in .NET 3.5.1.

[EDIT The application runs on 3.5.1 so either it is not realy fixed or I do something different]

Can I do something so that the GC can reclaim the memory of subform?

As soon as I remove the ToolStrip, the form subform can be garbage collected again.

MainForm

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

        private void button1_Click(object sender, EventArgs e)
        {
            SubForm subForm = new SubForm();
            subForm.ShowDialog();
        }
    }

SubForm

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

Instance Retention Graph with Toolstrip

Large Version

回答1:

You're showing a dialog, but never disposing it, so at least put it in a using() clause , or otherwise dispose it when appropriate. See more about ShowDialog here



回答2:

Put in a finaliser for the SubForm and write something to the console to see if the form is being destroyed. Something like...

~SubForm()
{
  Console.WriteLine("Destroyed!");
}

Then in the code where you create the form, after the ShowDialog returns, include GC.Collect() to do garbage collection. When you run the program, if you see the console message, then all is good. If you do not, you have a memory leak that may be caused by the ToolStrip memory leak.

If this is the case, call Dispose() on the ToolStrip in the SubForm's FormClosed event and try again. This works for me using .Net 2, which has the problem. If you run again, you should get the console message. If you do not, you may have another memory leak (eg. DateTimePicker)