2010-09-27 3 views
13

В C#, если я использую следующий кодСколько памяти использует пустой указатель?

Dictionary<int,object> dictionary = new Dictionary<int, object>(); 
dictionary.Add(1,null); 
dictionary.Add(2,new object()); 
dictionary[2] = null; 

Сколько памяти выделяется? делает каждый объект ссылки в словаре (словарь [1], словарь [2]) принимает размер указателя (32 или 64 бит) в куче? другими словами, когда я делаю словарь.Add (1, null), CLR автоматически создает 2 распределения в куче, один для int и один для нулевого указателя?

ответ

0

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

Итак, я предполагаю, что по крайней мере 2x64 бит выделяется, может быть, словарь нуждается в дополнительном пространстве для себя.

+0

Я согласен с ответом на ур, но у меня есть вопрос об этом. указатели - это переменные int32 или int64, поэтому, даже если u задает их null, у нас нет другого объекта в памяти, но все еще есть объекты int32 в качестве переменных указателя да? –

+0

@ Dr TJ: Указатели не являются объектами int32 или int64, но они имеют одинаковый размер. Ср Double имеет тот же размер, что и int64, но отличается от другого. Нулевой указатель представлен 32 или 64 нулевыми битами, и эти биты, очевидно, должны быть где-то сохранены. – MSalters

+0

Хорошо, спасибо за разъяснение ... –

15

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

Независимо от того, будет ли каждый добавочный вызов получать новые распределения (для хранения указателя) или нет, зависит от реализации Словаря. Обычно он имеет внутренний массив, который при необходимости изменяется по размеру.

В вашем примере я бы предположил, что при создании словаря уже выделено достаточно места для нескольких элементов. Таким образом, add (1, null) не будет выделять больше места.

Обновление: default initial capacity for Dictionary не указывается. В .NET 4.0 он начинается с 0, фактически, поэтому первый add создаст массив хранения.

+0

Отличный ответ спасибо! Я изучаю связанные списки - как система обрабатывает тот факт, что связанный список создает бесконечное количество нулевых указателей? Очевидно, что они не все используются, но создание узловой структуры с данными и указателем узла рекурсивно создает узлы указателя. Как это обрабатывается в памяти? У каждого нулевого указателя есть адрес памяти? Компьютеры динамически выделяют эту память по мере необходимости? – Federico

1

Само по себе нулевой указатель занимает 4 или 8 байт, в зависимости от того, работает ли он как 32-разрядный или 64-разрядный, как вы предполагали.

В данной коллекции может быть больше, чем это. Реализация Dictionary<TKey, TValue> использует как массив из Entry<TKey, TValue> структур, который содержит два int s, а также ключ и значение, а также массив целых чисел, используемых для индексирования в этот массив. Следовательно, даже если бы не было «растущей комнаты» (и, как правило, каждая), для каждой записи понадобилось бы 20 байт или 24 байт памяти (а не только 8 или 12 по величине ключа и значения) поверх накладных расходов для самого словаря (включая накладные расходы каждого массива).

Другие реализации и другие коллекции будут иметь другие накладные расходы. Они могут даже не хранить null для нулевой записи. null может быть полезным способом указания значения, которое не было записано, в этом случае специальное значение будет указывать фактическое значение null (особенно полезно в реализациях без блокировки словаря, где может быть полезно различать не только неустановленные и установленное значение, но между установкой unset, set и частично установленным значением).

Все, что вы можете сказать, это то, что настройка добавления значения null A) занимает некоторую память, а B) не занимает память, которая с ненулевым значением будет восприниматься самим объектом. Даже B) на самом деле не выполняется, поскольку, если этот объект также был сохранен в другом месте, тогда нет никакой дополнительной стоимости памяти при наличии другой ссылки в другом месте, помимо той, которая указана в самой ссылке, что делает реальную стоимость ее такой же, как хранение null.

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