2014-11-21 5 views
4

Мы запускаем очень простую функцию в консольном приложении, которое проходит через базы данных и перечисляет таблицу в переменную. Конечно, изначально он сделал больше, но мы разделили его на простое перечисление 1 таблицы.ObjectContext не сбор мусора

Мы заметили, что на каждом новом творении ObjectContext память растет примерно на 5 МБ. У нас есть инструкция using(), и даже при выполнении GC.Collect() память не освобождается.

Когда мы удаляем листинг таблицы и просто создаем новый ClassEntities, память остается очень низкой.

Мы попробовали все, что могли, чтобы уничтожить и собрать, но безрезультатно, в результате использования памяти более 1 ГБ.

Вот основная программа:

List <string> databases = (from x in admin_db.tblDbs select x.db_name).ToList(); 
foreach(var db_name in databases) { 
    Console.WriteLine("Current db:" + db_name); 
    var entityString = String.Format("metadata=<here we put the connection string>", db_name); 
    using(ClassEntities db = new ClassEntities(entityString)) { 
     try { 
      List <tblDepartment> departments = db.tblDepartments.ToList(); 
      departments = null; 
     } catch {} 
    } 
} 

Тогда ClassEntities (усеченную):

public partial class ClassEntities: ObjectContext { 
    public ClassEntities(): base("name=ClassEntities", "ClassEntities") { 
     this.ContextOptions.LazyLoadingEnabled = true; 
     OnContextCreated(); 
    } 
    public ClassEntities(string connectionString): base(connectionString, "ClassEntities") { 
     this.ContextOptions.LazyLoadingEnabled = true; 
     OnContextCreated(); 
    } 
    public ClassEntities(EntityConnection connection): base(connection, "ClassEntities") { 
     this.ContextOptions.LazyLoadingEnabled = true; 
     OnContextCreated(); 
    } 
} 

Любая помощь или идеи будут чрезвычайно оценены.

+2

Я не вижу ничего конкретного, что могло бы вызвать проблему. Мысли: сколько записей в «базах данных»? Сколько записей в 'tblDepartments'? Обратите внимание, что сборщик мусора не обязательно освобождает память сразу в конце блока 'using' (интервал, на котором он работает, не очень детерминирован). Попробуйте использовать профилировщик памяти, это может помочь. – PoweredByOrange

+0

Кроме того, вызов GC.Collect() не * заставляет * сбор мусора; он просто помещает объект для коллекции в следующий раз, когда GC запускается. Если вы запускаете его в режиме отладки, вы также можете увидеть нечетное поведение с GC. Наконец, обратите внимание, что GC не может работать, если ваш процесс не находится под давлением памяти - вы можете увидеть, что выглядит как завышенная память, которая никогда не вызовет проблемы. Все, что сказал,> 1 ГБ, кажется странным для процесса, который использует только ~ 5 МБ за раз. –

+1

@PhilSandler: из документации для ['GC.Collect()'] (http: // msdn.microsoft.com/en-us/library/xe0c2357(v=vs.110).aspx): «Заставляет немедленно собирать мусор всех поколений». То есть 'GC.Collect()' специально _does_ заставляет сборку мусора. –

ответ

0

Существует 2 условие для объекта, чтобы сборщик мусора:

  • Это ушло из сферы
  • Он больше не упоминаемая в программе

Как ваш скринкаст показывает имеют круглые ссылки, которые предотвращают ожидаемую сборку мусора.

Ваш список элементов ссылки соединений, которые в свою очередь ссылается на ваши вопросы (HorekoEntitiesNoLog)

Попробуйте следующее:

  • Определить полный граф ссылок на объекты, которые составляют ваши циклические ссылки объекты графа.
  • Идентифицировать и ввести точку (и) этой точки.
  • Очистите ссылку на любую точку входа графика.
  • Вызов GC.Collect().

Если память не освобождается после вызова GC.Collect, либо у вас отсутствуют ссылки на точки входа, либо ваш график не заполнен.