I repeated another simple experiment getting a System out of memory
exception: The project contains the following files: Form1.cs,
FormManager.cs, Program.cs.
Curiously if the line in the Form1.cs " dataGrid1.DataSource =
data.Tables[0];" is commented the memory leak is inexistent. It really
seems to be a bug in the garbage collector of the compact framework.
(it just happens in the compact framework).
->>>>Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SQLite;
namespace DeviceApplication3
{
public partial class Form1 : Form
{
private System.ComponentModel.IContainer components = null;
private System.Windows.Forms.MainMenu mainMenu1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.DataGrid dataGrid1;
private Timer timer1;
DataSet data;
public Form1(DataSet data)
{
this.data = data;
InitializeComponent();
}
void Form1_Closing(object sender, CancelEventArgs e)
{
data = null;
timer1.Dispose();
dataGrid1.Dispose();
label1.Dispose();
mainMenu1.Dispose();
}
private void Form1_Load(object sender, EventArgs e)
{
timer1.Enabled = true;
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.mainMenu1 = new System.Windows.Forms.MainMenu();
this.label1 = new System.Windows.Forms.Label();
this.dataGrid1 = new System.Windows.Forms.DataGrid();
this.timer1 = new System.Windows.Forms.Timer();
this.SuspendLayout();
//
// label1
//
this.label1.Location = new System.Drawing.Point(4, 4);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(222, 20);
this.label1.Text = "Memory use:";
//
// dataGrid1
//
this.dataGrid1.BackgroundColor =
System.Drawing.Color.FromArgb(((int)(((byte)(128)))),
((int)(((byte)(128)))), ((int)(((byte)(128)))));
this.dataGrid1.Location = new System.Drawing.Point(0, 40);
this.dataGrid1.Name = "dataGrid1";
this.dataGrid1.Size = new System.Drawing.Size(240, 200);
this.dataGrid1.TabIndex = 2;
//
// timer1
//
this.timer1.Tick += new
System.EventHandler(this.timer1_Tick);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(96F,
96F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Dpi;
this.AutoScroll = true;
this.ClientSize = new System.Drawing.Size(240, 268);
this.Controls.Add(this.dataGrid1);
this.Controls.Add(this.label1);
this.Menu = this.mainMenu1;
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be
disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#endregion
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Enabled = false;
label1.Text = "Memory use: " + GC.GetTotalMemory(true);
label1.Refresh();
dataGrid1.DataSource = data.Tables[0];
}
}
}
->>>>>FormManager.cs
using System;
using System.Data;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace DeviceApplication3
{
public class FormManager
{
List<Form> forms;
int maxFormNumber = 3;
Form applicationForm;
DataSet data;
public FormManager()
{
//I create the dummy data
data = new DataSet();
data.Tables.Add();
for (int j = 0; j < 10; j++)
{
data.Tables[0].Columns.Add();
}
for (int i = 0; i < 1000; i++)
{
DataRow dr = data.Tables[0].NewRow();
for (int j = 0; j < 10; j++)
{
dr[j] = "123123212312312312" +
Environment.TickCount.ToString() + "1241455357367465daff" +
Environment.TickCount;
}
data.Tables[0].Rows.Add(dr);
}
forms = new List<Form>();
//I Don't destroy the form that has the event pool (There
should just be always maxFormNumber+1 forms in memory)
applicationForm = new Form1(data);
forms.Add(applicationForm);
applicationForm.Show();
}
public void ExecuteAction()
{
Form form;
form = new Form1(data);
PushForm(form);
}
public void PushForm(Form form)
{
form.Show();
forms[forms.Count - 1].Hide();
forms.Add(form);
if (forms.Count > maxFormNumber)
{
if (forms[0] != applicationForm)
{
forms[0].Close();
forms[0].Dispose();
}
forms.RemoveAt(0);
}
}
public Form getCurrentForm()
{
return forms[forms.Count - 1];
}
}
}
->>>>>Program.cs
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Data;
namespace DeviceApplication3
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static Timer timer;
static int counter;
static FormManager manager;
[MTAThread]
static void Main()
{
timer = new Timer();
timer.Interval = 100;
timer.Tick += new EventHandler(timer_Tick);
manager = new FormManager();
timer.Enabled = true;
Application.Run(manager.getCurrentForm());
}
static void timer_Tick(object sender, EventArgs e)
{
timer.Enabled = false;
counter++;
manager.ExecuteAction();
if (counter % 100 == 0)
{
MessageBox.Show("Memory use: " +
GC.GetTotalMemory(true));
}
timer.Enabled = true;
}
}
}