MultiRowを貼り付けてデータ連結したFormの生成と削除を繰り返すとメモリリークが発生する
対象製品
MultiRow for Windows Forms 5.0J
状況
修正済み
詳細
フォーム上に配置したMultiRowにデータ連結を行っている場合、そのFormの生成と削除を繰り返すとメモリリークが発生します。
本現象は以下の方法で確認することができます。
[Visual Basic]
【Form1.vb】
Public Class Form1
Private ds As DataSet
Public Sub New()
' この呼び出しはデザイナーで必要です。
InitializeComponent()
' InitializeComponent() 呼び出しの後で初期化を追加します。
' データセットの作成
ds = New DataSet()
Dim dt As DataTable = ds.Tables.Add("TEST")
dt.Columns.Add("ColumnA", GetType(String))
dt.Columns.Add("ColumnB", GetType(String))
dt.Columns.Add("ColumnC", GetType(String))
dt.Columns.Add("ColumnD", GetType(String))
ds.AcceptChanges()
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
' メモリ消費量チェック(処理前)
System.Diagnostics.Debug.Print("check-pre: {0:###,###,### byte}", GC.GetTotalMemory(True))
Dim f2 As New Form2(ds.Tables("TEST"))
f2.ShowDialog()
f2.Dispose()
' メモリ消費量チェック(処理後)
System.Diagnostics.Debug.Print("check-pst: {0:###,###,### byte}", GC.GetTotalMemory(True))
End Sub
End Class
【Form2.vb】
Imports GrapeCity.Win.MultiRow
Public Class Form2
Private dt As DataTable
Public Sub New(table As DataTable)
' この呼び出しはデザイナーで必要です。
InitializeComponent()
' InitializeComponent() 呼び出しの後で初期化を追加します。
' データテーブルの取得
dt = table
' Formのイベント設定
AddHandler Me.FormClosing, AddressOf Me.Form2_FormClosing
' MultiRowの初期化
InitializeMultiRow()
End Sub
Private Sub Form2_FormClosing()
dt.Clear()
End Sub
Private Sub InitializeMultiRow()
' データの設定
For i As Integer = 0 To 9999
dt.Rows.Add(String.Format("A{0}", i), String.Format("B{0}", i), String.Format("C{0}", i), String.Format("D{0}", i))
Next
dt.AcceptChanges()
' MultiRowの設定
Dim template1 As Template = Template.Default
template1.Row.Cells(0).DataField = "ColumnA"
template1.Row.Cells(1).DataField = "ColumnB"
template1.Row.Cells(2).DataField = "ColumnC"
template1.Row.Cells(3).DataField = "ColumnD"
GcMultiRow1.Template = template1
GcMultiRow1.DataSource = dt
End Sub
End Class
[C#]
【Form1.cs】
public partial class Form1 : Form
{
private DataSet ds;
public Form1()
{
InitializeComponent();
// データセットの作成
ds = new DataSet();
DataTable dt = ds.Tables.Add("TEST");
dt.Columns.Add("ColumnA", typeof(string));
dt.Columns.Add("ColumnB", typeof(string));
dt.Columns.Add("ColumnC", typeof(string));
dt.Columns.Add("ColumnD", typeof(string));
ds.AcceptChanges();
}
private void button1_Click(object sender, EventArgs e)
{
// メモリ消費量チェック(処理前)
System.Diagnostics.Debug.Print("check-pre: {0:###,###,### byte}", GC.GetTotalMemory(true));
Form2 f2 = new Form2(ds.Tables["TEST"]);
f2.ShowDialog();
f2.Dispose();
// メモリ消費量チェック(処理後)
System.Diagnostics.Debug.Print("check-pst: {0:###,###,### byte}", GC.GetTotalMemory(true));
}
}
【Form2.cs】
using GrapeCity.Win.MultiRow;
public partial class Form2 : Form
{
private DataTable dt;
public Form2(DataTable table)
{
InitializeComponent();
// データテーブルの取得
dt = table;
// Formのイベント設定
this.FormClosing += new FormClosingEventHandler(Form2_FormClosing);
// MultiRowの初期化
InitializeMultiRow();
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
// データのクリア
dt.Clear();
}
private void InitializeMultiRow()
{
// データの設定
for (int i = 0; i < 10000; i++)
{
dt.Rows.Add(string.Format("A{0}", i), string.Format("B{0}", i), string.Format("C{0}", i), string.Format("D{0}", i));
}
dt.AcceptChanges();
// MultiRowの設定
Template template1 = Template.Default;
template1.Row.Cells[0].DataField = "ColumnA";
template1.Row.Cells[1].DataField = "ColumnB";
template1.Row.Cells[2].DataField = "ColumnC";
template1.Row.Cells[3].DataField = "ColumnD";
gcMultiRow1.Template = template1;
gcMultiRow1.DataSource = dt;
}
}
本現象は以下の方法で確認することができます。
新規のプロジェクトを作成する。
Form1にButton1を追加する。
プロジェクトにForm2を追加する。
Form2にGcMultiRow1を追加する。
Form1とForm2に下記のテストコードを追加する。
プロジェクトを実行して、Form1を表示する。
Button1をクリックして、Form2を表示する。
Form2を閉じる。
手順7、8の操作を繰り返す。
[Visual Basic]
【Form1.vb】
Public Class Form1
Private ds As DataSet
Public Sub New()
' この呼び出しはデザイナーで必要です。
InitializeComponent()
' InitializeComponent() 呼び出しの後で初期化を追加します。
' データセットの作成
ds = New DataSet()
Dim dt As DataTable = ds.Tables.Add("TEST")
dt.Columns.Add("ColumnA", GetType(String))
dt.Columns.Add("ColumnB", GetType(String))
dt.Columns.Add("ColumnC", GetType(String))
dt.Columns.Add("ColumnD", GetType(String))
ds.AcceptChanges()
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
' メモリ消費量チェック(処理前)
System.Diagnostics.Debug.Print("check-pre: {0:###,###,### byte}", GC.GetTotalMemory(True))
Dim f2 As New Form2(ds.Tables("TEST"))
f2.ShowDialog()
f2.Dispose()
' メモリ消費量チェック(処理後)
System.Diagnostics.Debug.Print("check-pst: {0:###,###,### byte}", GC.GetTotalMemory(True))
End Sub
End Class
【Form2.vb】
Imports GrapeCity.Win.MultiRow
Public Class Form2
Private dt As DataTable
Public Sub New(table As DataTable)
' この呼び出しはデザイナーで必要です。
InitializeComponent()
' InitializeComponent() 呼び出しの後で初期化を追加します。
' データテーブルの取得
dt = table
' Formのイベント設定
AddHandler Me.FormClosing, AddressOf Me.Form2_FormClosing
' MultiRowの初期化
InitializeMultiRow()
End Sub
Private Sub Form2_FormClosing()
dt.Clear()
End Sub
Private Sub InitializeMultiRow()
' データの設定
For i As Integer = 0 To 9999
dt.Rows.Add(String.Format("A{0}", i), String.Format("B{0}", i), String.Format("C{0}", i), String.Format("D{0}", i))
Next
dt.AcceptChanges()
' MultiRowの設定
Dim template1 As Template = Template.Default
template1.Row.Cells(0).DataField = "ColumnA"
template1.Row.Cells(1).DataField = "ColumnB"
template1.Row.Cells(2).DataField = "ColumnC"
template1.Row.Cells(3).DataField = "ColumnD"
GcMultiRow1.Template = template1
GcMultiRow1.DataSource = dt
End Sub
End Class
[C#]
【Form1.cs】
public partial class Form1 : Form
{
private DataSet ds;
public Form1()
{
InitializeComponent();
// データセットの作成
ds = new DataSet();
DataTable dt = ds.Tables.Add("TEST");
dt.Columns.Add("ColumnA", typeof(string));
dt.Columns.Add("ColumnB", typeof(string));
dt.Columns.Add("ColumnC", typeof(string));
dt.Columns.Add("ColumnD", typeof(string));
ds.AcceptChanges();
}
private void button1_Click(object sender, EventArgs e)
{
// メモリ消費量チェック(処理前)
System.Diagnostics.Debug.Print("check-pre: {0:###,###,### byte}", GC.GetTotalMemory(true));
Form2 f2 = new Form2(ds.Tables["TEST"]);
f2.ShowDialog();
f2.Dispose();
// メモリ消費量チェック(処理後)
System.Diagnostics.Debug.Print("check-pst: {0:###,###,### byte}", GC.GetTotalMemory(true));
}
}
【Form2.cs】
using GrapeCity.Win.MultiRow;
public partial class Form2 : Form
{
private DataTable dt;
public Form2(DataTable table)
{
InitializeComponent();
// データテーブルの取得
dt = table;
// Formのイベント設定
this.FormClosing += new FormClosingEventHandler(Form2_FormClosing);
// MultiRowの初期化
InitializeMultiRow();
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
// データのクリア
dt.Clear();
}
private void InitializeMultiRow()
{
// データの設定
for (int i = 0; i < 10000; i++)
{
dt.Rows.Add(string.Format("A{0}", i), string.Format("B{0}", i), string.Format("C{0}", i), string.Format("D{0}", i));
}
dt.AcceptChanges();
// MultiRowの設定
Template template1 = Template.Default;
template1.Row.Cells[0].DataField = "ColumnA";
template1.Row.Cells[1].DataField = "ColumnB";
template1.Row.Cells[2].DataField = "ColumnC";
template1.Row.Cells[3].DataField = "ColumnD";
gcMultiRow1.Template = template1;
gcMultiRow1.DataSource = dt;
}
}
回避方法
この現象はService Pack 2 (v5.0.2011.0513)で修正されています。
最新のService Packのダウンロードはこちら 。
最新のService Packのダウンロードはこちら 。
キーワード
MLTR08135