Большой объект куча дружественных IDictionary - PullRequest
10 голосов
/ 05 мая 2011

У нас есть приложение, которое содержит большое количество объектов за несколько Dictionary с, некоторые из которых непрерывно растут в течение всего жизненного цикла приложения (торговое приложение с большим количеством инструментов и постоянно растущими ордерами / сделками).

У нас проблемы с OutOfMemoryException s из-за фрагментации кучи больших объектов.

Чтобы противостоять этому, я попытался написать «большой» словарь, который реализован как двухуровневый словарь, где вселистовые словари недостаточно велики для размещения на LOH.Я использовал последовательный алгоритм хеширования, чтобы избежать необходимости перефразировать весь словарь, когда один сегмент становится слишком большим.Последовательное хэширование 'circle' - это TreeDictionary из библиотеки коллекций C5.

Мой вопрос заключается в том, существуют ли какие-либо более совершенные структуры данных (или, возможно, более совершенные реализации описанной мной) для C #?

Обновление

Это реализация для «большого» словаря: https://gist.github.com/956621

Я понимаю, что он не является надежным, поскольку ни порог кучи LOH не находится вспецификация, ни размер каждой записи в словаре или алгоритм масштабирования.Однако в настоящее время это лучшее, что я могу придумать, чтобы избежать взрыва приложения в полдень.

Ответы [ 2 ]

3 голосов
/ 05 мая 2011

Словарь - это неудачная структура данных, когда она самая большая в вашем приложении. Хэш-таблица часто удваивается в размере, когда она становится слишком полной, и это требует 150% перераспределения во время изменения размера, прямо в критическое время. Хеш-таблица работает великолепно, когда она гигантская, но требует последовательного выделения, что подчеркивает алгоритмы кучи.

Вы можете уменьшить эти недостатки с помощью многоуровневых хеш-таблиц, например, используя байт хеш-кода в качестве индекса для 256 хеш-таблиц. Это наверняка добавляет некоторые накладные расходы, но, что более важно, эта и другие стратегии наполняются опасностью, путаясь со случайностью, такой как хеш-коды, которые вы получаете, и потенциально делая вещи намного, намного хуже с точки зрения производительности. Использование этого подхода требует хорошего теоретического обоснования и серьезного эмпирического тестирования. Но это может сработать.

Другая стратегия состоит в том, чтобы предварительно выделить наибольшую структуру данных для наихудшего случая и выделить ее заранее. Нет необходимости в мелкомасштабном распределении, но теперь вы сталкиваетесь с угрозой катастрофического отказа, если он когда-либо закончится. Это вариант.

1 голос
/ 05 мая 2011

Я думаю, что это требует изменения алгоритма.

Из того, что я слышал и понимал, GC довольно хорош в упаковке и дефрагментации памяти. Итак, ваша проблема проистекает из простого факта, что вы сохраняете слишком много данных в памяти.

Сколько данных вы храните в памяти?

Вы думали об использовании базы данных? компактного может быть достаточно.

Или просто скажите своему клиенту, что для корректной работы вашего приложения ему нужно 16 ГБ памяти. И если вашему приложению нужны все эти 16 ГБ памяти, то определенно что-то не так.

Редактировать : Глядя на вашу проблему с другой стороны, и после прочтения вашей правки у меня возник вопрос: насколько велики ваши объекты? Или они содержат длинные списки или массивы? Как часто вы удаляете / добавляете эти объекты?

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

И, возможно, использование неизменяемых структур вместо изменяемых классов может облегчить фрагментацию.

...