2014-01-14 3 views
2

Я на .NET 4.0, так что есть предел 2 GBиз памяти С коллекцией

Это прибудет бросает аут исключения памяти о 1/2 времени

public IEnumerable<FTSword7bitThesaurus> FTSwordsPlusSelected 
{ 
    get 
    { 
     try 
     { 
      return FTSWords7bit.Select(w => new FTSword7bitThesaurus(this, w, selectedKeys.Contains(w.Key))); 
     } 

Трассировка стеки начинается:
System.Collections.Generic.List'1_setCapacity (значение int32)

Это код, который вызывает, что получить

<ListView Grid.Row="4" Grid.Column="1" x:Name="lvFTSWordsMine" 
           ItemsSource="{Binding ElementName=lvThesarus, Path=SelectedItem.FTSwordsPlusSelected, Mode=OneWay}" 
           ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Hidden" VerticalContentAlignment="Stretch"> 

Но что меня смущает это FTSwordsPlusSelected (должно быть) меньше, чем FTSWords7bit

Это единственные данные в FTSword7bitThesaurus
Один BOOL и две ссылки

public class FTSword7bitThesaurus : INotifyPropertyChanged 
{ 
    bool selected = false; 
    FTSword7bit fTSword; 
    FTSthersarus fTSthersarus; 

FTSWord7bit имеет в среднем 20 байт данных
Размер коллекции FTSWords7bit составляет 12 миллионов FTSWord7bit
Эта коллекция еще не выбрасывает исключение из памяти

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

selectedKeys является просто HashSet и не более чем 10000 и обычно менее 200

С тех пор как создается FTSWords7bit, вы считаете, что это происходит из-за фрагментации памяти?

Любые идеи о том, как избежать этой проблемы с памятью?

FTSWords7bit используется много, и я держусь, что
FTSword7bitThesaurus используется только один экран администратора, и я хочу, отбрасываются, когда они выходят из этого экрана
Большую часть времени, что сбор составляет менее 1 млн, но это нечетные набор данных
Если я могу только стабилизировать 12 миллионов я КИ
Мы можем даже жить с из памяти 1/2 времени, но это не вселять уверенность в пользователях
это собирается быть за пару месяцев до перехода на .NET 4.5

От a ccepted ответить
Исправление только пейджинг
Скорее всего, проблема непрерывный блок памяти не был доступен

public void NextPage() 
{ 
    page++; 
    NotifyPropertyChanged("FTSwordsPlusSelected"); 
} 

public IEnumerable<FTSword7bitThesaurus> FTSwordsPlusSelected 
{ 
    get 
    { 
     try 
     { 
      return FTSWords7bit.Skip(page * pageSize).Take(pageSize).Select(w => new FTSword7bitThesaurus(this, w, selectedKeys.Contains(w.Key))); 
     } 
+0

Какой профайлер вы используете? –

+0

@DavidKhaykin Я даже не помню, как я загрузил бесплатную версию и отбросил ее, когда она истекло. Когда я смотрел на отдельные объекты, FTSword7bitThesaurus был размером в 1/2 размера. – Paparazzi

+0

Сколько времени займет исключение из памяти? –

ответ

2

Проблема заключается в том, что не только делает ваш код ожидает очень большой непрерывный блок память (массив через List<>), но он также должен выделять дополнительную память для каждой записи в ListView. Я бы предположил, что накладные расходы, связанные с ListView, довольно сложны, и это вызывает проблему.

Там лежат несколько решений с различной степени сложности:

  • виртуализация данных - Это решение является лучшим для пользователей. По сути, элемент управления будет содержать только нужные ему строки в памяти. Конечно, ваши пользователи не смогут сказать, так что это лучшее и сложное решение. У этого post есть приличный пример. (Это похоже на поиск изображений Google).
  • Контроль пейджинга - Это решение больше похоже на вариант веб-сайта. Подумайте о нормальном Google, они не показывают бесконечные результаты, просто подмножество. Затем они позволяют выбрать следующую страницу для получения дополнительных результатов. Это можно сделать довольно хорошо с IEnumerable<>, потому что вы можете использовать Skip() и Take() для каждой страницы (скажем, у вас есть 25 записей на странице, тогда вы бы сделали Skip(25 * pageNumber).Take(25)). Я нахожу, что это решение намного проще создавать, но больше бремени для использования.
+0

Это экран администратора и часто не используется. Большинство данных имеют менее 1 миллиона строк. Я просто добавил кнопки, чтобы захватить миллион строк за раз. Из-за виртуализации уровня пользовательского интерфейса я не уверен, что ListView является проблемой. – Paparazzi

+0

На самом деле теперь, когда вы упоминаете об этом, я всегда думал, что все списки wpf используют виртуализацию данных уже. Может быть, просто воспользовавшись этим, это решит проблему. –

+0

Хотелось бы! Я бы поспорил, что это по крайней мере поможет ... – Andrew

Смежные вопросы