I am trying to chase a memory leak in a multiform C#.Net application, on Windows 7, VS 2008.
I found this SO post, which indicates that the second form's finalizer should be automatically called this.Dispose() doesn't release memory used by Form after closing it. However, it isn't working for me.
Each time a pop up the second form (which contains a large string, and a PictureBox), the amount of memory the app uses increases, even when I force a GC. Interestingly, the String's finalizer IS being called. I've add a log to both form's Dispose methods; Form2's dispose is being called.
The code is Form1 (main form)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace MemoryLeakTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
~Form1()
{
System.Diagnostics.Debugger.Log(0, "", "Form1.Destructor has been called.\n");
}
private void GC_Click(object sender, EventArgs e)
{
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
}
private void OpenForm_Click(object sender, EventArgs e)
{
Form secondForm = null;
if (secondForm == null)
{
secondForm = new Form2();
secondForm.Show();
}
secondForm = null;
}
private void UpdateMemory_Click(object sender, EventArgs e)
{
long memory = System.GC.GetTotalMemory(false);
this.MemoryUsage.Text = "Memory usage: " +
String.Format("{0:n}", memory) +
" bytes";
}
private void AllocateString_Click(object sender, EventArgs e)
{
// StringWrapper wrapper = new StringWrapper();
}
}
public class StringWrapper
{
String str = new String('*', 1024 * 1024);
~StringWrapper()
{
System.Diagnostics.Debugger.Log(0, "", "StringWrapper finalizer has been called.\n");
}
}
}
and Form2 is
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace MemoryLeakTest
{
public partial class Form2 : Form
{
StringWrapper wrapper = new StringWrapper();
public Form2()
{
InitializeComponent();
this.pictureBox1.Image = Image.FromFile("C:/Windows/Web/Wallpaper/Windows/img0.jpg");
}
~Form2()
{
System.Diagnostics.Debugger.Log(0, "", "Form2.Finalizer has been called.\n");
}
}
}
I haven't included the designer generated code, but can add it if need be