2010-09-02 132 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收集,因爲從函數範圍離開,缺少引用,即在函數結束時不再引用此變量,因此它將被收集。