在我们的代码中,有时会在控件中添加对数据对象的引用。比如使用树节点的Tag属性保存相应的对象,以便在界面操作中能简单的进行访问。因为其它地方不会引用这些数据,所以我们期望在控件被销毁时,垃圾回收机制能回收相应的内存。但当软件运行了一段时间后,内存使用量会变得非常大。下面是简化后的示例代码:
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[100][]; largeObject[i] = array; for (int j = 0; j < array.Length; ++j) { array[j] = new int[100]; } } return largeObject; } } static class Program { static void Main() { Application.Run(new MainForm()); } } }
代码中的checkGc变量是为了在输出中确认垃圾回收已经进行了。下面是输出结果:
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
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索private
, tag
, panel
, #FlowLayoutPanel
, before
after
造成内存泄露的原因、隐私泄露造成的危害、野外陷阱正确设置法、cell控件是否正确安装、打印控件没有正确安装,以便于您获取更多的相关知识。
时间: 2024-12-20 11:47:12