Сущности ADO.NET выдают исключение OutOfMemoryException.Как это предотвратить - PullRequest
0 голосов
/ 28 февраля 2011

Базовая таблица имеет столбцы int, guid и Filestream в SQL Server 2008 R2. Файловый поток отображается как байт []. Я наблюдаю, что потребление памяти продолжает расти. Что мне делать?

MyEntities bh = new MyEntities ();
foreach (var s in bh.TaskGraphs)
{
    try
    {
        using (var x = new MemoryStream(s.TaskGraph1))
        {
            //var t = TaskGraph.Load(x);
            //Validate(t);
        }
    }
    catch (Exception e)
    {                
    }
}

Вот схема использования памяти

enter image description here

Теперь я заметил, что выполнение bh.TaskGraphs.Select (p => new {p.TaskGraph1, p.StreamId} исключает исключение. Это связано с дочерней таблицей, связанной с этой таблицей?

Кстати, каждый BLOB ~ 3 МБ

Ответы [ 4 ]

1 голос
/ 28 февраля 2011

Платформа сущностей загружает сущность в контейнер сущностей, и контейнер имеет набор сущностей, который содержит локальную копию сущности, которая была извлечена из базы данных.У каждой сущности есть ссылка на соответствующий ей набор сущностей, и весь набор сущностей останется в памяти, а набор сущностей будет расти, пока вы будете загружать его из базы данных.

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

Далее в цикле for, пока вы выполняете итерацию, вы должны загрузить объект BLOB-объекта через новый контекст, обработать ваш байтовый массив и уничтожить ваш контекст в конце цикла for.Или вы также можете отсоединить объект от контейнера сущностей, что сделает его свободным для сборки мусора.

В существующем коде вы можете отсоединить вашу сущность, которая освободит память, которую она хранит.

MyEntities bh = new MyEntities ();
foreach (var s in bh.TaskGraphs)
{
    try
    {
        using (var x = new MemoryStream(s.TaskGraph1))
        {
            //var t = TaskGraph.Load(x);
            //Validate(t);
            bn.Detach(t);
        }
    }
    catch (Exception e)
    {                
    }
}
0 голосов
/ 28 февраля 2011

Я думаю, что таблица TaskGraph имеет много записей, поэтому при вызове bh.TaskGraphs она загружает всю таблицу в память, а двоичные данные в ней больше доступной памяти. Вы должны попытаться загрузить только те записи, которые вы хотите из базы данных, используя хранимую процедуру, иначе. но сначала попробуйте это:

using(MyEntities bh = new MyEntities())
{
    your code.....
}
0 голосов
/ 28 февраля 2011

Я не думаю, что есть простое решение для этого. См. Этот связанный вопрос: Обработка больших двоичных объектов в Entity Framework 4.0 в потоковом режиме

0 голосов
/ 28 февраля 2011

Трудно сказать без дополнительной информации, но я полагаю, что по крайней мере часть проблемы является следующей:

  1. Таблица TaskGraphs содержит много строк или столбец Filestream содержит много дат
  2. TaskGraph.Load и / или Validate сохраняют ссылку на эти данные, чтобы они не собирались мусором.
  3. Контекст объекта MyEntities сохраняет столбцы Filestream в памяти в течение определенного периода времени, прежде чем снова его освободить.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...