Вопрос

У меня есть следующий метод зацикливания через таблицу, изменяйте некоторые значения в каждой строке и сохраняете разводки обратно в базу данных. Чтобы все идут быстрее, я получу данные в наборах 10000 строк. Это большой стол с более 25 миллионов записей в нем.

Проблема в том, что мое приложение, похоже, не выпускает какую-либо память. Я пробовал редколировать records переменная к nothing Или явный отрезной сборщик мусора, но память остается там. Running встроенный Profiler VS10, я вижу, что виновник является system.linq.enumerable.tolist() Метод, который занимает более 98% моей памяти. Как освободить эту память после звонка saveChanges?

db = New databaseEntities
Dim size = 25000000
Dim stepSize = 10000
For i = 0 to size Step stepSize
  Dim sql = (From A In db.table).OrderBy(Function(A) A.Column).Skip(i).Take(stepSize)
  Dim records As New List(Of table)
  records = sql.ToList
  For Each record In records
    'do some work
  Next
  db.SaveChanges()
  records = Nothing
  GC.Collect()
Next
Это было полезно?

Решение

Репозиторий содержит ссылку на каждую структуру, это отслеживается, поэтому вы не сможете распоряжаться объектом, в то время как репозиторий живет и отслеживает его. Это означает, что вам либо нужно утилизировать репозиторий, либо отсоединить каждую сущность после того, как вы закончите обработку.

Вариант 1) Если «какая-то работа» не влияет на заказ, вы можете вернуть записи, вы можете переместить создание базы данных в петле для цикла и объявить его с помощью блока. Это должно привести к тому, что каждый блок сущностей будет выпущен каждый раз вокруг цикла

Вариант 2) Если ваша операция по существу параллельна, и то, что вы делаете с одной «таблицей», не имеют никаких зависимостей для любых других, то вы могли бы позвонить в базе данных. коллекционер, чтобы вернуть пространство сущности.

Глядя на ваш код, я подозреваю, что может быть использован любой из TOSE

Другие советы

Может быть, вы можете попробовать это: (Я не проверил его)

db.SaveChanges()
For Each record In records
    record.dispose ''only if class table got a dispose method
Next
records.clear
records = Nothing

Я ни в коем случае не являюсь Linq для SQL Expert, но я предполагаю, что в том, что CataContext кэширует все строки, которые вы прочитали, поэтому вы должны либо опозорить кеш, либо терять ссылку на DataContext.

Если вам не нужно Обновить Предприятия, используют MergeOption.NoTracking. Отказ Контекст больше не будет поддерживать ссылку на объект, а также не будет исправить.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top