In our code, there are times when you add a reference to a data object in a control. For example, use the Tag property of the tree node to save the object so that it can be easily accessed in the interface operation. Because the data is not referenced elsewhere, we expect the garbage collection mechanism to reclaim the appropriate memory when the control is destroyed. But when the software runs for a while, memory usage becomes very large. The following is a simplified sample code:
Using System;
Using System.Windows.Forms;
Namespace Memoryleak {public class Mainform:form {private Button Holderbutton;
Private Button Controlbutton;
Private FlowLayoutPanel panel;
Private Object CHECKGC;
Public MainForm () {dumpmemoryusage ("before allocate checkgc.");
CHECKGC = Makelargeobject ();
Dumpmemoryusage ("After allocate checkgc.");
Holderbutton = new Button ();
holderbutton.enabled = false;
Holderbutton.autosize = true;
Holderbutton.text = "The button holds large object."
Dumpmemoryusage ("Before allocate Holderbutton.tag.");
Holderbutton.tag = Makelargeobject ();
Dumpmemoryusage ("After allocate Holderbutton.tag.");
Controlbutton = new Button (); ContrOlbutton.autosize = true;
Controlbutton.text = "the button controls Holderbutton." Controlbutton.click + = (sender, E) => {dumpmemoryusage ("before release CHECKGC and
Holderbutton.tag. "); Panel.
Controls.remove (Holderbutton);
Holderbutton.dispose ();
Holderbutton = null;
CHECKGC = null;
Dumpmemoryusage ("After release CHECKGC and Holderbutton.tag.");
};
panel = new FlowLayoutPanel (); Panel.
AutoSize = true; Panel.
FlowDirection = Flowdirection.topdown; Panel.
Controls.Add (Controlbutton); Panel.
Controls.Add (Holderbutton);
Controls.Add (panel); private void Dumpmemoryusage (String msg) {GC.
Collect (); Console.
WriteLine (msg); Console.WriteLine (GC.
Gettotalmemory (true));
Private Object Makelargeobject () {var largeobject = new object[100]; for (int i = 0; i < largeobject.length ++i) {var array = new Int[1
00][];
Largeobject[i] = array; for (int j = 0; J < array.) Length;
++J) {Array[j] = new INT[100];
} return largeobject; } static class Program {static void Main () {A Pplication.
Run (New MainForm ()); }
}
}
The CHECKGC variable in the code is to confirm that the garbage collection has already been made in the output. The following are the output results:
Before allocate CHECKGC.
281576 after
allocate CHECKGC.
4605632
before allocate holderbutton.tag.
4606384 after
allocate holderbutton.tag.
8930480
before release CHECKGC and Holderbutton.tag.
8940016 after release
CHECKGC and Holderbutton.tag.
4616824