を上書きするとき、私はメモリリークを識別するためにテスト関数を実行しています:ミステリーメモリリーク静的なデータセット
[TestMethod]
public void DatabaseTools_Other_MemoryTest()
{
for (int i = 0; i < 100; i++)
{
try
{
var r = DatabaseTools.GetDataSet(true);
r = null;
}
catch (Exception e)
{
int EndPoint = i;
}
}
}
この方法の目標は、それがOutOfMemoryException例外に当たるまで(真)DatabaseTools.GetDataSetを呼び出すことです3回目または4回目のロード中に発生します。この関数にのみ「真」渡すとき
public static DataSet GetDataSet(bool setData, string sqlText = null, string strConnection = null)
{
sqlText = sqlText ?? FullFilemakerQuery;
if (setData)
{
Database = strConnection;
Data = new DataSet();
}
DataSet dataSet = new DataSet();
using (SqlConnection connection = GetConnectionString())
{
using (SqlDataAdapter dataAdapter = new SqlDataAdapter(sqlText, connection))
{
dataAdapter.SelectCommand.CommandType = System.Data.CommandType.Text;
if (setData)
{
dataAdapter.FillSchema(Data, SchemaType.Source);
DisableAutoIncrement(Data);
dataAdapter.Fill(Data);
NameTables(Data, sqlText);
BuildDataKeysAndRelations(Database);
dataSet = null;
}
else
{
dataAdapter.FillSchema(dataSet, SchemaType.Source);
DisableAutoIncrement(dataSet);
dataAdapter.Fill(dataSet);
NameTables(dataSet, sqlText);
}
}
connection.Close();
}
return dataSet ?? Data;
}
public static void NameTables(DataSet dataSet, string sqlText)
{
for (int i = 0; i < dataSet.Tables.Count; i++)
{
dataSet.Tables[i].TableName = sqlText.Split(';')[i].Split(Dividers, StringSplitOptions.None)[1].Trim();
}
}
public static void DisableAutoIncrement(DataSet data)
{
foreach (DataTable T in data.Tables)
{
T.PrimaryKey.Select(c => { c.AutoIncrement = false; return c; }).ToList();
}
}
、それはすべてのものを選択し、静的FullFileMakerQueryにSQLTEXT等しい設定します。しかし、私はそれを理解するように、これは実際に今までにこれがDatabaseTools.GetDataSetあるhappen-べきではありませんプログラムはデータベースから使用することができ、デフォルトのデータベース名を取得します(データベースにはnullまたは空の値が指定された場合、デフォルトに設定されるカスタムセッターがあります)、静的データを新しいDataSetに設定します。この時点でnullに設定しようとしましたが(変更なし)、エラーを引き起こしたData.Dispose()を使用しようとしました。この関数はグローバルデータも設定せずにデータセットを返すだけなので、新しいDataSetデータセットを初期化します。次に、標準のconnect、data adapter、fillschema、load dataを実行します。
おかしな:メモリテスト機能にブレークポイントを設定し、ダンプを保存、データセットをロードすることによって、一度(System.Data.Common.StringStorageに約36,000バイト)は、少ないメモリを使用して再ロード、メモリの一部を要します再読み込みを行うには、をもう一度メモリ(前と同じ場所で約120,000バイト)使用します。もう一度リロードすると、OutOfMemoryExceptionのためにさらに多くのメモリとクラッシュが使用されます。この時点で何が原因か分かりません。
私は 'BuildDataKeysAndRelations'メソッドを疑っています。そのメソッドの内容を表示できますか? –
ここには、データの取得とデータの保持というものが混在しています。これらの2つの懸念を分けておけば、もっとクリーンなプログラム(そして間違いを見やすくする方法)が得られます。 – nvoigt
@ ThariqNugrohotomo私もやったが、その行がメモリリークに影響を与えないとコメントしています。 –