1 DataGridView、1 DataTable などのアプリケーションがあります。
私の「実行」方法(編集):
private void btnRunSQL_click()
{
string strConnStr = tbConnStr.Text; // connection string from textbox
string strSQL = tbSql.Text; // query from textbox
SqlDataAdapter dataAdapter = new SqlDataAdapter(strSQL, strConnStr);
SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter);
// clean memory
// dtData DataTable is declared in main form class
dtData = new DataTable();
dataAdapter.Fill(dtData);
showMemoryUsage();
}
これは、メモリをチェックする方法です:
public void showMemoryUsage()
{
Process proc = Process.GetCurrentProcess();
this.Text = "Peak memory: " + proc.PeakWorkingSet64 / 1024 / 1024 + "MB";
Application.DoEvents(); // force form refresh
}
この関数を複数回実行すると、ますます多くのメモリが使用されます。私は非常に大きなデータ セット (1000000 行) に取り組んでおり、いくつかの大きなクエリの後、アプリを再起動する必要があります。
1M 行のクエリを実行した後、メモリ使用量は約 900MB、2 回目の実行では 1100MB、1300MB などです。
DataTable を再初期化するとメモリが解放されると思っていましたが、そうではありません。そのため、BindingSource (DataGridView に接続) を再初期化しましたが、それも役に立ちませんでした。最後に、BindingSource と DataGridView にコメントしました。
後で追加:
DataAdapter の破棄は役に立ちませんでした。
DataGridView とバインディング ソースを削除しました。助けにはなりませんでした。
解決策(いくつかの回答をマージして、漏れのないテストアプリを作成しました)
using System;
using System.Data;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Diagnostics;
// to run this code you need form and controls:
// TextBox tbConnStr - textbox with SQL Server connection string
// TextBox tbSQL - for SQL query to run/test
// TextBox tbLog - for log display
// Button btnRunSQL with OnClick event set to proper method
// Button btnRunTest with OnClick event set to proper method
namespace Test_datatable
{
public partial class Form1 : Form
{
DataTable dt; // i need this global
public Form1()
{
InitializeComponent();
}
private void btnRunSQL_Click(object sender, EventArgs e)
{
log("Method starts.");
string strConnStr = tbConnStr.Text;
string strSQL = tbSQL.Text;
using (SqlDataAdapter da = new SqlDataAdapter(strSQL, strConnStr))
{
using (SqlCommandBuilder cb = new SqlCommandBuilder(da))
{
if (dt != null)
{
dt.Clear();
dt.Dispose();
log("DataTable cleared and disposed.");
}
dt = new DataTable();
da.Fill(dt);
log("DataTable filled.");
}
}
log("Method ends.");
tbLog.Text += Environment.NewLine;
}
// prints time, string and memory usage on textbox
private void log(string text)
{
tbLog.Text += DateTime.Now.ToString()
+ " " + text + memory() +
Environment.NewLine;
Application.DoEvents(); // force form refresh
}
// returns memory use as string, example: "Memory: 123MB"
private string memory()
{
Process proc = Process.GetCurrentProcess();
return " Peak memory: " + (proc.PeakWorkingSet64 / 1024 / 1024).ToString() + "MB ";
}
// test method for 10 runs
private void btnRunTest_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++)
{
btnRunSQL_Click(new object(), new EventArgs());
}
}
}
}