Вопрос по .net – Отдельные объекты по-прежнему ограничены размером 2 ГБ в CLR 4.0?

39

Насколько я понимаю, существует ограничение в 2 ГБ для отдельных экземпляров в .NET. Я не обращал на это большого внимания, поскольку до сих пор работал в основном на 32-битных ОС. На 32 но это более или менее искусственное ограничение в любом случае. Тем не менее, я был очень удивлен, узнав, чтоэто ограничение также распространяется на 64-битные .NET.

Так как коллекции, такие какList<T> использовать массив для хранения элементов, это означает, что приложение .NET, работающее в 32-разрядной среде, сможет хранить в списке вдвое больше элементов ссылочного типа по сравнению с тем же приложением, работающим в 64-разрядной системе. Это довольно удивительно, IMO.

Кто-нибудь знает, учтено ли это ограничение в CLR 4.0 (на данный момент у меня нет установки 4.0 под рукой).

Обновление 2012: Начиная с .NET 4.5, в системах x64 разработчики теперь могут выделять объекты размером больше (намного больше), чем 2 ГБ. Ограничение в 2 ГБ мертвое.centerspace.net/blog/nmath/large-matrices-and-vectors/… Paul
Правильная ссылка кажетсяcenterspace.net/blog/nmath/large-matrices-and-vectors Brian Rasmussen
Даже исправленные ссылки мертвы :( RBT
Попробуйте эту ссылку для получения информации о том, как обойти ограничение 2 ГБ (MSDN)msdn.microsoft.com/en-us/library/hh285054(v=vs.110).aspx John Thoits

Ваш Ответ

3   ответа
16

.4.5 позволяет создавать массивы размером более 2 ГБ на 64-битных платформах. Эта функция не включена по умолчанию, ее необходимо включить через файл конфигурации с помощью элемента gcAllowVeryLargeObjects.

http://msdn.microsoft.com/en-us/library/hh285054(v=vs.110).aspx

Все еще только 4 ГБ !? почему они не могут делать реальные 64-битные?
@Rick k; так как большойint[] сuint.MaxValue элементы?
Таким образом, вы ограничены 4 ГБ, если вам нужноbyte[]& # X2026;
@MarcGravell & quot; Максимальное количество элементов в массиве - UInt32.MaxValue. & Quot;
Я не заметил. Спасибо за ссылку. Brian Rasmussen
13

кто использует числовые библиотеки классов в .NET, хранит свои матрицы в виде массивов. Это так, чтобы нативные библиотеки можно было вызывать для вычисления числа. Ограничение в 2 ГБ серьезно ограничивает размер матриц, возможных в 64-битном .NET. БольшеВот.

Мы говорили с Microsoft об этой проблеме. Это вряд ли будет исправлено в .NET 4.0, но они казались очень восприимчивыми к поиску решения. Я думаю, что в итоге мы получим массивы с длинными индексами, но, скорее всего, это какой-то гигантский объект BLOB-объекта.
Как производительность массива с плавающей запятой 65536 * 65536 сравнивается с производительностью 65536 массивов с 65536 числами с плавающей запятой? Производительность 256 массивов с 256 числами с плавающей запятой будет ниже, чем у массива 256 * 256, так как последний будет иметь лучшую локальность кэша, а первый не выиграет, но если кто-то обращается к строкам матрицы, которые достаточно локализованы, чтобы получить выгоду из локальности кэша, я думаю, процессор сможет кэшировать ссылки на таблицы объектов.
53

чем это - вы обрабатываете пространство, когда вы работаете в .NET в 32-битной системе, что намного меньше теоретического предела. В 32-битных приложениях .NET мой опыт показывает, что вы всегда будете склонны начинать получать ошибки памяти где-то в пределах 1,2-1,4 ГБ использования памяти (некоторые люди говорят, что они могут получить до 1,6 ... но я никогда не видел этого ). Конечно, это не проблема для 64-битных систем.

При этом один массив ссылочных типов 2 ГБ, даже в 64-битных системах, представляет собой огромное количество объектов. Даже с 8-байтовыми ссылками у вас есть возможность выделить массив из 268 435 456 ссылок на объекты, каждая из которых может быть очень большой (до 2 ГБ, больше, если они используют вложенные объекты). Это больше памяти, чем требовалось бы большинству приложений.

Один из членовКоманда CLR написала об этом в блоге, с некоторыми вариантами способов обойти эти ограничения. В 64-битной системе что-то вроде его BigArray & lt; T & gt; было бы жизнеспособным решением выделить любое количество объектов в массив - намного больше, чем ограничение на один объект в 2 ГБ. P / Invoke также позволяет вам выделять большие массивы.

Изменить: я должен был упомянуть об этом, а также - я не думаю, что это поведение изменилось для .NET 4. Поведение не изменилось с самого начала .NET.

Изменить: .NET 4.5 теперь будет иметь возможность в x64 явно разрешить объекты размером более 2 ГБ, установивgcAllowVeryLargeObjects в app.config.

Я знаю обо всех ограничениях 32-битной системы, но это не совсем вопрос моего вопроса. Сюрпризом стало то, что на 64 битах все на самом деле хуже Я посмотрю на сообщение в блоге. Спасибо за ссылку. Brian Rasmussen
Брайан: Это еще один (хотя и незначительный, IMO) недостаток - 64-битный или 32-битный. Есть много причин НЕ переходить на 64-битную архитектуру, но люди, кажется, об этом забывают, думая, что 64-битная система автоматически лучше.
Я читал, что Mono поддерживает 64-битные массивы в C # (например, массивы с более чем 2 ^ 32 записями)
Да, Моно делает это. Обратите внимание, что теоретическая возможность существует для всех реализаций CLR (все массивы имеютlong LongLength собственности), но пока только Mono фактически использовал это.
Нет проблем - я просто добавил, что в 64-битной версии она не хуже, чем в 32-битной. Теоретический предел составляет 1/2 от объектов, но, поскольку вы действительно ограничены общим объемом пространства процесса 1,4 ГБ, нет способа создать массив ссылок на объекты, даже близкий к половине допустимого размера. (Каждая ссылка требует, чтобы она указывала на что-то, а также на размер ссылки ... так что вы действительно ограничиваете большую часть времени около 1 / 4gb ссылок в .NET 32bit).

Похожие вопросы