C # chunked массив - PullRequest
       1

C # chunked массив

4 голосов
/ 03 ноября 2010

Мне нужно выделить очень большие массивы простых структур (1 ГБ ОЗУ). После нескольких выделений / освобождений память становится фрагментированной и генерируется исключение OutOfMemory.

Это меньше 32 бит. Я бы предпочел не использовать 64-битную версию из-за снижения производительности - это же приложение работает на 30% медленнее в 64-битном режиме.

Вам известны некоторые реализации совместимых с IList массивов, которые выделяют память порциями, а не все сразу? Это позволило бы избежать проблемы фрагментации памяти.

Ответы [ 3 ]

3 голосов
/ 03 ноября 2010

Джош Уильямс представил класс BigArray<T> в своем блоге с использованием массива чанков:

BigArray<T>, обойти ограничение размера массива 2 ГБ

В этом смежном вопросе вы найдете больше полезной информации:

C # 2-мерные массивы огромных размеров

Простым временным исправлением может быть включение переключателя 3 ГБ для вашего приложения. Это позволяет вашему приложению использовать более 32 ГБ для каждого процесса в Windows. Однако имейте в виду, что максимальный размер объекта, который допускает CLR, по-прежнему составляет 2 ГБ. Переключатель может быть включен с помощью действия после сборки для вашего основного исполняемого файла:

call "$(DevEnvDir)..\tools\vsvars32.bat"
editbin.exe /LARGEADDRESSAWARE "$(TargetPath)"
1 голос
/ 03 ноября 2010

При создании экземпляра массива .Net пытается найти непрерывную часть памяти для вашего массива.Поскольку общий предел памяти для 32-разрядного приложения составляет 2 ГБ, вы можете увидеть, что будет трудно найти такой блок после нескольких выделений.

  1. Вы можете попробовать использовать что-то вродеLinkedList<T>, чтобы избежать необходимости в непрерывном выделении, или реструктурируйте свой код, чтобы сделать эти куски меньше (хотя вы не будете в полной безопасности, этого также не произойдет с массивом 500 МБ).

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

  2. Если вы можете использовать IEnumerable вместо IList для передачи ваших данных остальной части вашей программы, вы сможете свернуть этот список, используя метод SelectMany LINQ.

  3. И, наконец, вы можете просто реализовать интерфейс IList в пользовательском классе и использовать несколько меньших массивов под капотом.

0 голосов
/ 03 ноября 2010

Будет ли LinkedList работать для вас?http://msdn.microsoft.com/en-us/library/he2s3bh7.aspx

...