Сколько памяти использует нулевой указатель? - PullRequest
16 голосов
/ 27 сентября 2010

В C #, если я использую следующий код

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

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

Ответы [ 3 ]

16 голосов
/ 27 сентября 2010

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

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

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

Обновление: Начальная емкость по умолчанию для словаря не указана. На самом деле в .NET 4.0 он начинается с 0, поэтому при первом добавлении будет создан массив хранения.

2 голосов
/ 27 сентября 2010

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

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

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

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

0 голосов
/ 27 сентября 2010

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

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

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