Упаковка создает мусор в.NET?

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

Например, StringBuilder. AppendFormat () имеет эти перегрузки:

StringBuilder.AppendFormat(string format, object arg0);
StringBuilder.AppendFormat(string format, object arg0, object arg1);
StringBuilder.AppendFormat(string format, object arg0, object arg1, object arg2);
StringBuilder.AppendFormat(string format, params object[] args);

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

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

6
задан Cygon 9 February 2010 в 06:59
поделиться

3 ответа

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

Бокс создает мусор - или, скорее, каждый раз, когда вы упаковываете, он создает новый объект, который, вероятно, в конечном итоге станет мусором. (У нет , чтобы стать мусором - у вас может быть ссылка на этот объект до конца жизни приложения; это довольно редко.)

Однако вы можете ] есть кеш для бокса. Действительно, Java подходит для небольших чисел. Если вы напишете:

Integer x = 5;
Integer y = 5;
System.out.println(x == y); // Reference comparison

, то гарантированно будет напечатано true .

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

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

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

8
ответ дан 9 December 2019 в 22:34
поделиться

Вы задаете неправильный вопрос.

Перегрузка, на которую вы указываете, - это оптимизация для прямого вызова параметров. Это означает, что компилятор поместит переменные в arg_0, arg_1, arg_2, arg_3, возможно и больше, но IL имеет их только для быстрого доступа. Остальное в любом случае проходит через стек и, следовательно, не намного эффективнее, чем вызов функции с типизированным параметром.

Для вызова функции с типизированным параметром он фактически создает массив за сценариями и отправляет его в функцию как arg_1 (в данном случае, когда arg_0 используется строкой).

0
ответ дан 9 December 2019 в 22:34
поделиться

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

Создание метода перегрузки с 3 или менее аргументами является (как вы заметили) предотвращением построения массивов и является оптимизацией производительности. См. раздел "Рассмотрение возможности предоставления специальных перегрузок и путей кода для вызовов с небольшим количеством аргументов в крайне чувствительных к производительности API" на Members with a Variable Number of Parameters.

Однако создание массива принципиально отличается от боксирования типа значения. Вызов любой перегрузки StringBuilder.AppendFormat всегда будет опрашивать аргументы, которые являются типами значений, так как параметр типизируется как объект, независимо от того, создан массив или нет. Подробнее о боксировании см. в разделе "Боксирование и деблокирование" по ссылке .NET: Тип Основы.

3
ответ дан 9 December 2019 в 22:34
поделиться
Другие вопросы по тегам:

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