MultiRowを貼り付けてデータ連結したFormの生成と削除を繰り返すとメモリリークが発生する

文書番号 : 30943     文書種別 : 不具合     最終更新日 : 2011/06/07
文書を印刷する
対象製品
MultiRow for Windows Forms 5.0J
状況
修正済み
詳細
フォーム上に配置したMultiRowにデータ連結を行っている場合、そのFormの生成と削除を繰り返すとメモリリークが発生します。

本現象は以下の方法で確認することができます。

  1. 新規のプロジェクトを作成する。
  2. Form1にButton1を追加する。
  3. プロジェクトにForm2を追加する。
  4. Form2にGcMultiRow1を追加する。
  5. Form1とForm2に下記のテストコードを追加する。
  6. プロジェクトを実行して、Form1を表示する。
  7. Button1をクリックして、Form2を表示する。
  8. Form2を閉じる。
  9. 手順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のダウンロードはこちら
キーワード
MLTR08135