2012-05-23 3 views
0

Редактировать: Пожалуйста, игнорируйте этот вопрос, это ошибка программиста PBCAK.Вложенные объекты, вызывающие потерю памяти «утечка» в .NET 4 LinkedList

Часть 1

Как я могу исправить утечка памяти в этом коде?

Часть 2

Если решение включает в себя добавление Dispose к SummaryEntity, как я должен избавиться от объекта, если у меня есть второй список (резюме-из-резюме), который ссылается на это? Предположим, я хочу, чтобы в резюме резюме-оф-10 самых последних SummaryEntities

Код

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Collections.Concurrent; 

namespace TestDoesLinkedListLeak 
{ 
    public class SummaryEntity 
    { 
     public object PlaceHolder { get; set; } 
     /// <summary> 
     /// Note: This is a Field instead of a Property to support Interlockd methods 
     /// </summary> 
     public int ReferenceCount; 
     public int Value; 
     public int? PreviousValue { get; set; } 
    } 
    class FrequencyOfMatchedHash : Dictionary<int, SummaryEntity> 
    { 
     private object frequencyOfMatchedHashLock; 

     public void AddRecordHash(int hashCode, int value, object placeHolder) 
     { 
      SummaryEntity se = null; 
      try 
      { 
       se = new SummaryEntity(); 
       se.ReferenceCount = 1; 
       se.PlaceHolder = placeHolder; 
       se.Value = value; 

       lock (this.frequencyOfMatchedHashLock) 
       { 
        if (this.ContainsKey(hashCode)) 
        { 
         System.Threading.Interlocked.Add(ref this[hashCode].Value, value); 
         System.Threading.Interlocked.Increment(ref this[hashCode].ReferenceCount); 
        } 
        else 
        { 
         this.Add(hashCode, se); 
        } 
       } 

       //this.AddOrUpdate(hashCode, se , 
       // (k, v) => 
       //  { 
       //   System.Threading.Interlocked.Add(ref v.Value , value); 
       //   System.Threading.Interlocked.Increment(ref v.ReferenceCount); 
       //   return v; 
       //  }); 
      } 
      finally 
      { 
       //se.Dispose(); 

      } 
     } 
    } 
    class LLDateNode //:IDisposable 
    { 
     public FrequencyOfMatchedHash FrequencyOfMatch { get; set; } 
     public DateTime Date { get; set; } 

     public override string ToString() 
     { 
      return Date + " Count:" + FrequencyOfMatch.Count; 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      try 
      { 
       Console.WriteLine("start"); 
       Console.WriteLine("Total Memory: {0} Forced Collect: {1}", GC.GetTotalMemory(false), GC.GetTotalMemory(true)); 
       LinkedList<LLDateNode> tmp = new LinkedList<LLDateNode>(); 
       for (int i = 0; i < 111111; i++) 
       { 
        // Console.Write("."); 
        tmp.AddFirst(new LLDateNode() { Date = DateTime.UtcNow, FrequencyOfMatch = new FrequencyOfMatchedHash() }); 
       } 
       Console.WriteLine(); 
       Console.WriteLine("Done create, now delete"); 
       Console.WriteLine("Total Memory: {0} Forced Collect: {1}", GC.GetTotalMemory(false), GC.GetTotalMemory(true)); 
       Console.WriteLine(); 

       for (int i = 0; i < tmp.Count; i++) 
       { 
        //Console.Write("x"); 
        tmp.RemoveFirst(); 
       } 
       Console.WriteLine(); 
       Console.WriteLine("End of program"); 
       Console.WriteLine("Total Memory: {0} Forced Collect: {1}", GC.GetTotalMemory(false), GC.GetTotalMemory(true)); 
       Console.ReadLine(); 
       Console.ReadLine(); 
       Console.ReadLine(); 
       Console.ReadLine(); 

      } 
      catch 
      { 

      } 
     } 
    } 
} 

Выход

start 
Total Memory: 186836 Forced Collect: 106656 

Done create, now delete 
Total Memory: 11222752 Forced Collect: 11217844 


End of program 
Total Memory: 11226036 Forced Collect: 5662320 
+0

Почему вы ссылаетесь на счет? –

+0

@EugenRieck Я не должен был размещать свойство 'ReferenceCount'. Это выдержка из приложения для разработки. 'Больше информации, не имеющей непосредственного отношения к этому вопросу': у меня есть словарь (не указан здесь), который отслеживает объекты по hashcode и связанный список для отслеживания объектов по дате. Поскольку объекты возрастают из связанного списка, я удаляю их из словаря. Словарь представляет собой более или менее обобщенную и скользящую совокупность момента времени. Счетчик ссылок - это сумма всех связанных элементов списка, которые являются «активными» и включены в резюме. – LamonteCristo

ответ

0

Я могу ошибаться, но я думаю, что когда вы звоните tmp.RemoveFirst(), размер tmp.Count становится меньше, а i продолжает расти. Итак, вы удаляете только половину Dictionary. Либо не увеличивайте значение i, либо поместите tmp.Count в переменную, а затем используйте это в условии цикла. Учитывая, что размер вашего последнего Force Collect составляет около половины, похоже, что это может быть ваша проблема.

+0

Вы правы. Я пытаюсь воспроизвести утечку памяти в своем приложении, и у меня возникли проблемы. Я думал, что обнуллю проблему, вернусь к чертежной доске. – LamonteCristo

Смежные вопросы