Размер массива ограничен верхним пределом интервала (2147483647)?

Я только что понял, моя модель комнаты была совершенно неправильной, это правильная форма:

module.exports = (sequelize, DataTypes) => {
    const Room = sequelize.define('Room', {
        type: DataTypes.ENUM('WANT', 'HAVE', 'SWAP'),
        building: DataTypes.ENUM('AA', 'BB', 'CC'),
        block: DataTypes.STRING,
        room: DataTypes.SMALLINT
    })
    return Room
}
6
задан Robert Harvey 11 February 2011 в 23:58
поделиться

5 ответов

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

Как упомянуто в этой статье существует предел на 2 ГБ на любой объект в .NET. Для всего x86, x64 и IA64.

Как с 32-разрядными операционными системами Windows, существует предел на 2 ГБ на размер объекта, который можно создать при запуске 64-разрядного управляемого приложения на 64-разрядной операционной системе Windows.

Также при определении массива, слишком большого на стеке у Вас будет переполнение стека. При определении массива на "куче" он попытается выделить все это в одном большом непрерывном блоке. Было бы лучше использовать ArrayList, который имеет неявное динамическое выделение на "куче". Это не позволит Вам заканчивать 2 ГБ, но вероятно позволит Вам становиться ближе к нему.

Я думаю, что предел размера стека будет больше, только если Вы используете x64 или архитектуру IA64 и операционную систему. Используя x64 или IA64 у Вас будет 64-разрядная allocatable память вместо 32-разрядного.

Если Вы не можете выделить список массива внезапно, можно, вероятно, выделить его в частях.

Используя список массива и добавление 1 объекта за один раз на машине x64 Windows 2008 с 6 ГБ RAM, большинство я могу добраться, ArrayList к является размером: 134217728. Таким образом, я действительно думаю, что необходимо найти лучшее решение проблемы, которая не использует в качестве большой памяти. Возможно, при записи в файл вместо того, чтобы использовать RAM.

12
ответ дан 8 December 2019 в 03:28
поделиться

Я полагаю, что даже в CLR на 64 бита, существует предел 2 ГБ (или возможно 1 ГБ - я не могу помнить точно) на объект. Это препятствовало бы тому, чтобы Вы создали больший массив. Факт тот Массив. CreateInstance только берет аргументы Int32 в пользу размеров, является наводящим на размышления также.

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

2
ответ дан 8 December 2019 в 03:28
поделиться

Предел массива, afaik, зафиксирован как int32 даже на 64-разрядном. Существует ограничение на максимальном размере отдельного объекта. Однако у Вас мог быть хороший большой зубчатый массив довольно легко.

Хуже; потому что ссылки больше в x64 для массивов касательно типа, Вы на самом деле получаете меньше элементов в едином массиве.

Посмотрите здесь:

Я получил много запросов относительно того, почему 64-разрядная версия 2,0 времен выполнения .NET все еще имеет размеры максимума массива, ограниченные 2 ГБ. Учитывая, что это, кажется, горячая тема в последнее время, я изобразил немного фона, и обсуждение опций обойти это ограничение было в порядке.

Сначала некоторый фон; в 2,0 версиях времени выполнения .NET (CLR) мы сделали сознательное проектное решение сохранить максимальный размер объекта позволенным в "куче" GC на уровне 2 ГБ, даже на 64-разрядной версии времени выполнения. Это совпадает с текущими 1,1 реализациями 32-разрядного CLR, однако Вам было бы трудно на самом деле уметь выделить объект на 2 ГБ на 32-разрядном CLR, потому что виртуальное адресное пространство просто слишком фрагментируется, чтобы реалистично найти дыру на 2 ГБ. Обычно люди особенно не обеспокоены созданием типов, которые были бы> 2 ГБ при инстанцировании (или где угодно закройтесь), однако так как массивы являются просто специальным видом управляемого типа, которые создаются в управляемой "куче", которую они также переносят от этого ограничения.


Нужно отметить, что в.NET 4.5 предел емкости памяти дополнительно удален флагом gcAllowVeryLargeObjects, однако, это не изменяет максимальный размер размера. Ключевой пункт - то, что, если у Вас есть массивы пользовательского типа или массивы мультиразмера, затем можно теперь пойти вне 2 ГБ в емкости памяти.

8
ответ дан 8 December 2019 в 03:28
поделиться

Вам не нужен массив, настолько большой вообще.

Когда Ваш метод сталкивается с проблемами ресурса, только посмотрите на то, как развернуть ресурсы, посмотреть на метод также.:)

Вот класс, который использует буфер на 3 МБ для вычисления начал с помощью решета Эратосфена. Класс отслеживает то, как далеко Вы вычислили начала, и когда диапазон должен быть расширен, он создает буфер для тестирования еще 3 миллионов чисел.

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

Я сделал некоторое тестирование, и буферные приблизительно 3 МБ являются самыми эффективными.

public class Primes {

   private const int _blockSize = 3000000;

   private List<long> _primes;
   private long _next;

   public Primes() {
      _primes = new List<long>() { 2, 3, 5, 7, 11, 13, 17, 19 };
      _next = 23;
   }

   private void Expand() {
      bool[] sieve = new bool[_blockSize];
      foreach (long prime in _primes) {
         for (long i = ((_next + prime - 1L) / prime) * prime - _next;
            i < _blockSize; i += prime) {
            sieve[i] = true;
         }
      }
      for (int i = 0; i < _blockSize; i++) {
         if (!sieve[i]) {
            _primes.Add(_next);
            for (long j = i + _next; j < _blockSize; j += _next) {
               sieve[j] = true;
            }
         }
         _next++;
      }
   }

   public long this[int index] {
      get {
         if (index < 0) throw new IndexOutOfRangeException();
         while (index >= _primes.Count) {
            Expand();
         }
         return _primes[index];
      }
   }

   public bool IsPrime(long number) {
      while (_primes[_primes.Count - 1] < number) {
         Expand();
      }
      return _primes.BinarySearch(number) >= 0;
   }

}
6
ответ дан 8 December 2019 в 03:28
поделиться

Я - в значительной степени новичок с C# (т.е. изучение его на этой неделе), таким образом, я не уверен в точных деталях того, как ArrayList реализован. Однако я предположил бы, что, поскольку Вы не определили тип для примера ArrayList, затем массив был бы выделен как массив ссылок на объект. Это могло бы хорошо означать, что Вы на самом деле выделяете 4-8Gb из памяти в зависимости от архитектуры.

1
ответ дан 8 December 2019 в 03:28
поделиться
Другие вопросы по тегам:

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