2016-08-30 4 views
2

Учитывая, что массиву выделена фиксированная область памяти, вполне понятно, что длина массива неизменна.Как массивы обрабатываются в памяти?

Предположим, у меня есть Array [10] - это будет правильно распределять 10 слотов смежной памяти? И именно потому, что эти слоты смежны и в заранее определенных местах индексированные поисковые запросы бывают быстрыми.

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

Как это работает .Net? Я бы предположил, что он выделяет не последовательную память для хранения фактических данных в объектах, но я бы хотел получить авторитетный ответ на это. Например - использует ли он только не последовательную память, если объект превышает определенный размер? Что делать, если объект постоянно меняется по размеру, будет ли он пытаться оптимизировать местоположение хранилища?

Рассмотрим этого класса:

public class MyClass 
{ 
    public MyClass[] PotentiallyHugeNestedStructure 
} 

Теперь, если у меня есть массив MyClass и при запуске выполнения выделяющего к подразделам массивов и подразделы массивов. Я могу получить огромную коллекцию зубчатых массивов.

Так как же .net справится с этим, в памяти?

+3

* Фактические объекты в массиве *?!Нет, массив содержит ссылки на расположение памяти объектов (в управляемой куче), а не на самих объектах! – user3185569

+0

@ user3185569, так что они действительно просто упорядоченный список? –

+0

'Фактические объекты в массиве могут быть одного типа, но данные, которые они хранят, могут значительно отличаться по размеру. Даже если данные отличаются, хранилище, выделенное для каждого индекса, одинаково (int 4 байта) до тех пор, пока выделенная память может хранить значение, хранящееся для этого блока – Sherlock

ответ

3

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

Так что в рамках размера самого массива (как вы указали) нет недостатка в наличии массива объектов над массивом примитивных типов (кроме накладных расходов на создание самих объектов, которые элементы массива ссылка, которая не имеет ничего общего с размером массива в памяти).

В рамках доступа к элементам по индексу нет разницы, так как к ним обращаются по индексу. Несомненно, накладные расходы для извлечения объекта по ссылке из кучи, но это очень быстро (поскольку ссылка обычно представляет собой число, которое представляет смещение в ячейку памяти).

На рисунке ниже демонстрирует массивы, удерживающие ссылочные типы против массивов, занимающих типы значений:

enter image description here

Изображение из: CLR Via C# Джеффри Рихтер

myControls является массивом объектов, так что каждый элемент содержит либо Null (по умолчанию), либо ссылку на объект (4 байта для 32-разрядных систем и 8 байтов для 64-разрядных систем).

Сторона Примечание: Верхний указано на рисунке, содержит информацию о массиве:

  • Dimension
  • Нижняя граница каждого измерения (0 в большинстве случаев)
  • Длина самого массив.
+1

_ «Таким образом, нет абсолютно никакого недостатка в наличии массива объектов над массивом примитивных типов. Вы можете получить доступ к любому объекту в списке через индекс очень быстро» _ - по разным причинам это утверждение опасно неверен. Существует множество сценариев, в которых массив типов значений значительно превосходит массив ссылочных типов. Одним из главных факторов является локальность памяти и ее влияние на кеширование, но есть и другие проблемы. –

+0

@PeterDuniho Я думаю, что я написал недостаточно ясно. Я упоминал это как ответ на то, что сказал ОП. Он, хотя массив объектов занимает больше места в памяти, чем массив примитивных типов, что не обязательно верно. Это также может быть наоборот, поскольку для некоторых типов значений требуется больше памяти, чем ссылка. Надеюсь, теперь редактирование станет ясным. – user3185569

+0

Просьба привести пример типа значения, который, выполняя то же эффективное задание, что и эквивалентный ссылочный тип, использует _more_ память, чем эквивалентный ссылочный тип. –

Смежные вопросы