我在一个帖子中有一些代码。代码的主要功能是调用其他方法,这些方法将内容写入SQL数据库,如下所示:
private void doWriteToDb()
{
while (true)
{
try
{
if (q.Count == 0) qFlag.WaitOne();
PFDbItem dbItem = null;
lock (qLock)
{
dbItem = q.Dequeue();
}
if (dbItem != null)
{
System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
//write it off
PFResult result = dbItem.Result;
double frequency = dbItem.Frequency;
int i = dbItem.InChannel;
int j = dbItem.OutChannel;
long detail, param, reading, res;
detail = PFCoreMethods.AddNewTestDetail(DbTables, _dicTestHeaders[result.Name.ToString().ToLower()]);
param = PFCoreMethods.AddNewTestParameter(DbTables, detail, "Frequency");
PFCoreMethods.AddNewTestParameterValue(DbTables, param, frequency.ToString());
param = PFCoreMethods.AddNewTestParameter(DbTables, detail, "In channel");
PFCoreMethods.AddNewTestParameterValue(DbTables, param, i.ToString());
param = PFCoreMethods.AddNewTestParameter(DbTables, detail, "Out channel");
PFCoreMethods.AddNewTestParameterValue(DbTables, param, j.ToString());
param = PFCoreMethods.AddNewTestParameter(DbTables, detail, "Spec");
PFCoreMethods.AddNewTestParameterValue(DbTables, param, result.Spec);
dbItem.Dispose();
dqcnt++;
sw.Stop();
}
}
catch (Exception ex)
{
}
}
}
AddNewTestParameter方法正在使用具有SQL代码的第三方类。目前我无法访问其内部。
DbTables是一个集合对象,其属性是由第三方程序创建的表对象。程序只使用一个DbTable对象。
问题在于,随着时间的推移(几个小时),AddNewTestParameter方法调用的时间越来越长,从大约10ms开始到大约1秒。
q是一个包含对象的队列,这些对象包含写入数据库的必要信息。主线程将项目添加到此队列中。线程只是将它们取出,写入并处理它们。 q.Count不超过1,尽管随着数据库写入速度变慢,q.Count上升,因为dequeueing无法赶上。最糟糕的是,q.Count超过30,000。我总共在数据库中写了150,000多个条目。
在SQL端,我在服务器上运行了一些跟踪,并且跟踪显示内部SQL总是需要大约10ms,即使在C#代码本身需要1秒时也是如此。
所以,目前,我有2个怀疑:
我的代码就是问题所在。该线程是低优先级的,也许这可能会影响性能。此外,在观察了20分钟的内存使用后,我看到它以大约100K / min的速度上升,CPU使用率似乎在%2-5左右不变。我怎样才能弄清楚内存泄漏的位置?我可以将其指向代码的特定部分吗?
第三方代码就是问题所在。我怎么能证明这一点?有哪些方法可以观察并确认问题出在第三方代码中?
答案 0 :(得分:2)
无论如何,如果我不得不提出建议,我会看看DBTables ......如果那是一个集合,也许你忘了重置它,所以每当你调用它时它还有一个元素......所以过了一会儿O(n ^ 2)或类似的东西的第三方例程开始降级,因为它期望20个表的最坏情况并且你提供1000个。
编辑:好的,我会放弃队列中的问题,因为出列应该是一个非常快的操作(无论如何你都可以测量它)。它仍然指向DBTables集合越来越大,你在第一次x次迭代后检查它的大小吗?
Edit2:好的,另一种方法,假设AddNewTestParameter 完全它的含义...添加一个新参数然后添加到内部集合。现在,有两种选择,如果是这种情况,要么你应该通过在每次迭代后调用“ClearParameters”函数来清除该集合,然后它将是你的错,或者你没有这样的功能然后它是第3代码故障。这也可以解释你的记忆力损失(尽管也可能与不断增长的队列有关)