2010-09-02 135 views
1

我正在剖析singltone中的下面的代码,发现很多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) 
    { 
    } 
} 

工人将速率日志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

你如何确定有内存泄漏? – linuxuser27 2010-09-02 06:41:40

+3

这不是一个解决方案,但你是否已经认为异常正在发生并且无法识别?也许在catch块中添加一些日志可能会给你一些线索。 – 2010-09-02 06:42:46

+4

我认为你的拼写发生了内存泄漏。 – leppie 2010-09-02 06:48:57

回答

1

我遇到过同样的问题。这可能是一个真正的解释,但我找不到它。

我认为,因为我在while(true)循环GC不会运行。我不知道这是否是MS的.NET框架(.NET 3.5)实现的人工制品,但这正是我所经历的。

我减轻内存堆积的方法是将GC.Collect();放在循环的底部。

我有一种感觉,这是与未处置的SqlConnection对象有关。

+1

嘿, 显然,这并不是SqlConnection对象,因为我对应用程序进行了剖析,并且我只使用了一个SqlConnection open。无论如何,放一个GC.Collect()是一个糟糕的实践,特别是当你的应用程序使用大量内存来处理时。 – user437631 2010-09-04 14:18:03

+0

这是不好的做法,但如果你找不到真正的罪魁祸首,并且你被告知要完成它,有时最好解决问题并继续前进。如果我有机会尝试找到真正的问题。 – 2010-09-04 14:41:48

3

停止吞咽所有例外将是我会建议的第一个地方开始。

+0

嗨,大家好, 我删除了只有样本的所有日志记录。有一个日志作家,并没有执行...我可以detemine有一个内存泄漏根据蚂蚁探查器。 – user437631 2010-09-02 07:34:25

+0

@starskythehutch,一个简短的问题,你能给我一些关于如何做适当的异常处理以避免内存泄漏的信息吗?我总是认为展开堆栈不会导致内存泄漏。 – 2010-09-02 07:58:12

+0

@Akash - 你如何确定发生了什么,如果你吞下那些不是被设计为被捕获的异常,或者说你正在使用的任何框架都表示出一些更基本的失败? – starskythehutch 2010-09-02 12:20:20

2

您肯定会清除队列和临时列表temp(这是不必要的,因为它有资格收集even before you assign null to the reference)。在这一点上,我认为你的问题更可能与下面一行有关。

m_ConnectionDataAccess.InsertRateLog(item); 

您正在向另一个方法传递对RateLog的引用。您尚未提供此方法的任何详细信息,因此我无法消除它将自己的引用副本存储在单独的数据结构中的可能性。

+0

嗨,感谢您的帮助。 m_ConnectionDataAccess.InsertRateLog(item)是一种将日志插入数据库的方法,如下所示:(请参见原始问题) – user437631 2010-09-04 08:58:52

1

无需清理。无论如何,它都会被GC收集,因为从函数范围离开,缺少引用,即在函数结束时不再引用此变量,因此它将被收集。