我正在对单个单元内的下面的代码进行分析,发现很多Rate对象都保存在内存中,而且清除它们。
protected void FetchingRates()
{
int count = 0;
while (true)
{
try
{
if (m_RatesQueue.Count > 0)
{
List<RateLog> temp = null;
lock (m_RatesQueue)
{
temp = new List<RateLog>();
temp.AddRange(m_RatesQueue);
m_RatesQueue.Clear();
}
foreach (RateLog item in temp)
{
m_ConnectionDataAccess.InsertRateLog(item);
}
temp.Clear();
temp = null;
}
count++;
Thread.Sleep(int.Parse(ConfigurationManager.AppSettings["RatesIntreval"].ToString()));
}
catch (Exception ex)
{
}
}
}
通过以下方式插入队列:
public void InsertLogRecord(RateLog msg)
{
try
{
if (m_RatesQueue != null)
{
//lock (((ICollection)m_queue).SyncRoot)
lock (m_RatesQueue)
{
//insert new job to the line and release the thread to continue working.
m_RatesQueue.Add(msg);
}
}
}
catch (Exception ex)
{
}
}
worker将速率日志插入DB,如下所示:
internal int InsertRateLog(RateLog item)
{
try
{
SqlCommand dbc = GetStoredProcCommand("InsertRateMonitoring");
if (dbc == null)
return 0;
dbc.Parameters.Add(new SqlParameter("@HostName", item.HostName));
dbc.Parameters.Add(new SqlParameter("@RateType", item.RateType));
dbc.Parameters.Add(new SqlParameter("@LastUpdated", item.LastUpdated));
return ExecuteNonQuery(dbc);
}
catch (Exception ex)
{
return 0;
}
}
任何人都看到可能的内存泄漏?
答案 0 :(得分:3)
停止吞咽所有异常将是我建议的第一个开始。
答案 1 :(得分:2)
您当然正在清除队列和临时列表temp
(这是不必要的,因为它有资格收集even before you assign null
to the reference)。此时我认为您的问题更可能与以下行有关。
m_ConnectionDataAccess.InsertRateLog(item);
您正在将对RateLog
的引用传递给另一种方法。您尚未提供有关此方法的任何详细信息,因此我无法消除它将其自己的引用副本存储在单独的数据结构中的可能性。
答案 2 :(得分:1)
无需清除和清空List<RateLog> temp
。无论如何它都将被GC收集,因为从函数范围中缺少引用,即在函数端没有更多对此变量的引用,因此它将被收集。
答案 3 :(得分:1)
我遇到过同样的问题。可能有一个真正的解释,但我找不到它。
我认为因为我在while(true)
循环中,GC不会运行。我不知道这是否是MS实现.NET框架(.NET 3.5)的人工制品,但这正是我所经历的。
我减少记忆堆积的方法是将GC.Collect();
放在循环的底部。
我感觉这与未曝光的SqlConnection
对象有关。