Нахождение, сколько памяти я могу выделить для массива в C # - PullRequest
4 голосов
/ 07 декабря 2008

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

Есть ли способ программно определить, сколько памяти доступно, скажем, как можно большему массиву байтов?

Спасибо

Ответы [ 6 ]

10 голосов
/ 07 декабря 2008

Что ж, использование одного огромного массива связано с рядом проблем: фрагментация памяти, смежные блоки, ограничение максимального размера объекта и т. Д. Если вам нужно много данных, я бы порекомендовал создать класс, имитирующий большой массив, использующий множество меньших (но все еще больших) массивов, каждый из которых имеет фиксированный размер - то есть индексатор делится, чтобы найти соответствующий массив, а затем использует%, чтобы получить смещение внутри этого массива.

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

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

3 голосов
/ 19 июня 2009

Чтобы обеспечить достаточно свободной памяти, вы можете использовать MemoryFailPoint . Если память не может быть выделена, то будет сгенерировано InsufficientMemoryException , которое вы можете перехватить и обработать соответствующим образом.

2 голосов
/ 07 декабря 2008

Краткий ответ - «нет». Есть два ресурса верхнего уровня, к которым нужно будет обращаться

  1. Самый большой блок нераспределенного виртуального адресного пространства, доступный процессу
  2. Объем доступного пространства файла подкачки.

Как правильно сказал Марк Гравелл, вы добьетесь успеха на 64-битной платформе. Здесь каждый процесс имеет огромное виртуальное адресное пространство. Это эффективно решит вашу первую проблему. Вы также должны убедиться, что файл подкачки большой.

Но есть лучший способ, который ограничен только свободным пространством на вашем диске: файлы с отображением в памяти. Вы можете создать большое сопоставление (скажем, 512 МБ) в произвольно большом файле и перемещать его при обработке данных. Обратите внимание, не забудьте открыть его для эксклюзивного доступа.

1 голос
/ 07 декабря 2008

Если вам нужны действительно большие массивы, не используйте CLR. Mono поддерживает индексы 64-битных массивов, что позволяет в полной мере использовать ресурсы памяти.

0 голосов
/ 28 октября 2009

Самый большой массив, который можно выделить в 64-разрядной программе .NET, составляет 2 ГБ. (Другая ссылка.)

Вы можете легко узнать, сколько доступных байтов достаточно:


Using pc As New System.Diagnostics.PerformanceCounter("Memory", "Available Bytes")
  FreeBytes = pc.NextValue();
End Using

Учитывая эту информацию, вы сможете принять решение.

0 голосов
/ 28 октября 2009

Полагаю, бинарный поиск мог бы быть подходящим способом. Во-первых, начните с выделения 1 байта, если это удастся, освободите этот байт (установите для объекта значение null) и удвойте его до 2 байтов. Продолжайте до тех пор, пока вы не сможете больше выделять средства и не найдете предел, который можно считать «нижним пределом».

Правильное количество байтов, которое может быть выделено (назовем его x ), находится в интервале ниже <<strong> x <2 * <strong>ниже . Продолжайте поиск этого интервала, используя бинарный поиск.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...