我正在运行测试功能来识别内存泄漏:
[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;
}
}
}
此方法的目标是调用DatabaseTools.GetDataSet(true),直到它遇到在第3次或第4次加载期间发生的OutOfMemoryException。但是,据我所知,这实际上不应该发生 - 这是DatabaseTools.GetDataSet:
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();
}
}
当只通过&#39; true&#39;对于这个函数,它将sqlText设置为等于静态FullFileMakerQuery,它选择程序可以从数据库中使用的所有内容,然后获取默认数据库名称(Database有一个自定义setter,当给定null或空值时,它将自己设置为默认),并将静态数据设置为新的DataSet。我们已经尝试在此时将其设置为null(无更改),并且我们尝试使用导致错误的Data.Dispose()。因为此函数也可以在不设置全局数据的情况下返回数据集,所以我们初始化一个新的DataSet数据集。然后我们做标准连接,数据适配器,fillschema,加载数据。
奇怪:通过在内存测试函数中设置断点并保存转储,加载数据集一次需要一些内存,重新加载它使用 less 内存(在System.Data中大约36,000字节。 Common.StringStorage)然后重新加载它再使用 more 内存(在与之前相同的地方大约120,000个字节)。如果我们再次重新加载它,它会因为OutOfMemoryException而使用更多的内存和崩溃,此时我不知道是什么原因造成的。
答案 0 :(得分:0)
在再次致电.Dispose()
之前,您永远不会在DataSet
上致电new
,也不会在返回值和静态变量上致电using
。
由于您已经在其他课程中使用.Dispose()
块,我想您知道如何在其上实际调用$fileDir = '/home2/divine/Symfony/src/App/Bundle/Resources/public/files';
$form['my_file']->getData()->move($fileDir, 'book.pdf');
。
启用Visual Studio静态代码分析,如果您忘记这样做,它会向您发出警告。