Как освободить память?
-
28-09-2019 - |
Вопрос
У меня есть следующий метод зацикливания через таблицу, изменяйте некоторые значения в каждой строке и сохраняете разводки обратно в базу данных. Чтобы все идут быстрее, я получу данные в наборах 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
. Отказ Контекст больше не будет поддерживать ссылку на объект, а также не будет исправить.