单例中可能存在内存泄漏吗?
我以前问过这个问题,但没有真正的答案。有人可以帮忙吗? 我正在对单例中的以下代码进行分析,发现许多 Rate 对象 (List
) 仍保留在内存中,尽管我清除了它们。
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)
{
Logger.Log(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)
{
Logger.Log(ex);
}
}
工作人员将速率日志插入数据库,如下所示:
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)
{
Logger.Log(ex);
return 0;
}
}
有人发现可能存在内存泄漏吗?
I've asked this question before with no real answer. Can anybody help?
I'm profiling the below code inside a singleton and found that a lot of Rate objects (List<Rate>
) are kept in memory although I clear them.
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)
{
Logger.Log(ex);
}
}
}
The insertion to the queue is made by:
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)
{
Logger.Log(ex);
}
}
The worker inserts rate log into DB as follows:
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)
{
Logger.Log(ex);
return 0;
}
}
Any one sees a possible memory leak?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
看起来您没有处理挂在 RateLog 上的
SqlCommand
。Looks like you are not disposing of your
SqlCommand
which is hanging onto a RateLog.RateLog
对象。我建议您从创建
RateLog
对象的位置开始查看代码,并记下保存引用的所有位置。以下是一些需要考虑的事项。RateLog
对象是否订阅了任何事件?RateLog
对象的集合?您还应该考虑将所有线程安全样板封装在类中。
这将使您的代码更加清晰:
RateLog
objects from being collected by the GC.I recommend you look through your code starting where the
RateLog
objects are being created and take note of all the places a reference is being held. Here are some things to consider.RateLog
objects subscribed to any events?RateLog
objects sitting somewhere in a static class?You should also consider encapsulating all your thread safety boilerplate in class.
This will make your code a lot clearer:
Clear() 函数解构列表。但是 RateLog 实例呢?他们的解构函数被调用了吗?那么锁呢,也许这可以防止 RateLog 被删除。
the Clear() function deconstructs the List. But what about the RateLog instances? Is their deconstructor called? What about the lock, maybe this prevents that the RateLog from beeing deleted.
将
temp
创建移到循环之外怎么样?您可能不允许 GC 进行清理。在
temp.Clear()
之后,您可以尝试添加GC.Collect();
。这不应该是永久的解决方案,但可以用于您的分析,以查看对象最终是否被清理。如果没有,那么某处可能仍然附加有参考或事件。How about moving the
temp
creation outside the loop. You are probably not allowing the GC to clean up.After
temp.Clear()
you might try addingGC.Collect();
. This should NOT be the permanent solution, but could be used for your profiling to see if the objects get cleaned up eventually. If not, then there might still be a reference or event attached somewhere.