2012-06-21 3 views
0

Я испытываю исключения OutOfMemory в своем приложении, когда извлекает из базы данных. Это приложение C# .Net, использующее Linq2Sql.Linq2Sql из памяти исключение

Я попытался использовать GC.GetTotalMemory(), чтобы узнать, сколько памяти занято до и после вызова базы данных. Это дает приятную, хотя и не совсем точную картину того, что происходит. Когда я смотрю в диспетчере задач Windows можно видеть, что пик рабочего набора не меньше, при выборке данных в виде страничной образом, используя следующий код:

public static void PreloadPaged() 
{ 
    int NoPoints = PointRepository.Count(); 
    int pagesize = 50000; 
    int fetchedRows = 0; 

    while (fetchedRows < NoPoints) 
    { 
     PreloadPointEntity.Points.AddRange(PointRepository.ReadPaged(pagesize, fetchedRows)); 
     PointRepository.ReadPointCollections(); 
     PreloadPointEntity.PointCollections.Count()); 
     fetchedRows += pagesize; 
    } 
} 


private static List<PointEntity> ReadPaged(int pagesize, int fetchedRows) 
{ 
    DataModel dataContext = InstantiateDataModel(); 
    var Points = (from p in dataContext.PointDatas 
       select p.ToEntity()); 

    return Points.Skip(fetchedRows).Take(pagesize).ToList(); 
} 

Я предполагаю, что это код Linq2Sql, который использует вверх по память, а не повторно использовать ее или освобождать ее потом, но что я могу сделать, чтобы получить печать в памяти?

Я заметил, что он использует в 10 раз больше памяти для извлечения данных, как и для хранения их в моем списке. Я подумал о том, чтобы вызвать сборщика мусора, но я бы предпочел избежать его.

+2

Почему вам нужно, чтобы строки «50000» были удалены сразу? –

+0

Что вы намерены делать с этими сущностями дальше? –

+0

50000 - это только мой размер страницы, выбранный для экспериментальной цели, я предварительно выбираю сетку координат, которую все нужно обработать. Поэтому я просто храню их в списке объектов и получаю от них доступ вместо того, чтобы создавать новое соединение с БД каждый раз, когда мне нужна другая координата. – Keller

ответ

2

Вы извлекаете слишком много данных и сохраняете их в памяти, поэтому вы получаете исключение OOM.

1 из 2 вещей происходит:

  1. вы загружаете чрезмерное количество данных, когда пользователь будет просматривать только подмножество результатов и/или это первая попытка данных «кэширование».
  2. вам нужны все эти данные, но для получения доступа к данным используется неверная технология (Linq2Sql).

, если это первый, вам необходимо либо

  1. нагрузки меньшие порции данных (20-50 записей, не 50K или всё)
  2. если это только для отображения, то запрос проекция того, что необходимо, а не сама сущность.

, если это второй, чем использование инструмента ETL, предназначенного для управления большими объемами данных. Я предпочитаю Rhino.ETL, но SSIS также работает.

+0

Возможно, Linq2SQL - это не лучшая структура для использования в объемах данных, я рассмотрю инструменты ETL, которые вы предлагаете здесь, спасибо. – Keller