Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Детали реализации стека — часть первая

Anna | 17.06.2014 | нет комментариев
Какое-то время назад я писал о том, что «ссылки» — это не «адреса», когда речь идёт о C# и размещении его объектов в памяти. Правда это подлинно так, но это каждого лишь деталь реализации, но не толк «ссылки». Иная деталь реализации, которую Зачастую путают с сутью — это то, что «память под важнейшие типы (value types) выдается на стеке». Я Зачастую это вижу, потому что именно так написано в нашей документации.

Фактически всякая статья, которую я вижу, детально описывает (Зачастую неверно) что такое стек и что основное отличие между важными и ссылочными типами — это то, что важные типы располагаются на стеке. Я уверен Вы можете обнаружить уйма примеров таких статей в сети.

Я считаю, что определение важных типов, которое основанное на деталях реализации, а не на их отслеживаемом поведении единовременно и запутывающее, и не вовсе верное. Особенно важной колляцией объекта важного типа является не то как он располагается в памяти, а то как они ведут себя с точки зрения семантики: «объекты важных типов» неизменно передаются «по значению», т.е. копируются. Если бы основные отличия между ссылочными и важными типами были бы в деталях расположения в памяти, то мы бы назвали их «типы в куче» и «типы на стеке». Но в всеобщем случае это не имеет никакого отношения к сути. В всеобщем случае значимо то как экземпляры важных типов копируются и сравниваются.

К сожалению документация не сосредоточена на особенно важных колляциях, но сосредоточена на деталях реализации и упускает суть важных типов. Я бы дюже хотел, Дабы все те статьи, которые поясняют, «что такое стек» взамен этого поясняли бы что такое «копирование по значению» и как недопонимание этого механизма может стать поводом ошибок.

Заявление о том, что важнейшие типы располагаются на стеке в всеобщем случае не правильно. В документации на MSDN верно подмечено, что важнейшие типы располагаются на стеке изредка. Скажем, поле типа int в ссылочном типе — это часть объекта этого типа и, как и каждый объект его поле расположено в куче. Та же история с локальными переменными, которые попадают в замыкание неизвестных способов (*), потому что они по сути становятся полями спрятанного класса и тоже располагаются в куче, так что локальные переменные могут располагаться в куче даже если они важного типа.

Короче говоря, мы имеем трактование, которое ничего не поясняет. Отбросив соображения продуктивности что ещё, с точки зрения ожиданий разработчика может принудить CLRjitter поместить переменную типа int на стеке, а не в куче? Ничего, пока не нарушается спецификация система может выбирать особенно результативную тактику генерирования кода.

Ага, никто не обещал, что операционная система поверх которой реализован CLI предоставляет массив размером в 1 мегабайт под наименованием «стек». Windows традиционно делает это и данный одно мегабайтный массив хорошее место для того, Дабы результативно беречь небольшие объекты с коротким временем жизни, но нет никаких требований либо гарантий, что операционная система предоставляет такого рода конструкцию либо что jitter будет её применять. В тезисе Jitter может решить создавать все локальные переменные в куче не смотря на потерю продуктивности, это будет трудиться пока семантические требования к важным типам выполняются.

Ещё дрянней думать, что важные типы «стремительные и маленькие» а ссылочные «крупные и неторопливые». Подлинно, важнейшие типы могут быть сгенерированные jitter-ом в код на стеке, тот, что дюже стремителен как при выделении, так и при чистке памяти. Но при этом крупные конструкции, создаваемые на куче, такие как массив элементов важного типа, тоже создаются дюже стремительно при условии, что они инициализируются значениями по умолчанию. И ссылочные типы занимают дополнительное место в памяти. И безусловно существуют такие данные, когда важные типа дают огромный выигрыш в продуктивности. Но в подавляющем большинстве программ то, как локальные переменные создаются и уничтожаются не может быть тесным местом с точки зрения продуктивности.

Нано оптимизации по перевоплощению ссылочных типов в важнейшие дающие несколько наносекунд выигрыша не стоят того. Это необходимо делать только если данные профайлера показали, что существуют реальные задачи которые могут быть решены применением важных типов взамен ссылочных. У меня нет таких данных. При выборе применять ссылочный либо важный тип я неизменно руководствуюсь тем как тип, тот, что я создаю должен вести себя семантически.

(*) объективно и для блока итератора.

От переводчика: в последнее время мне вновь вывалилась вероятность провести несколько собеседований и Зачастую на вопрос «что такое важные и ссылочные типы» я слышал «важные типы — это типы, экземпляры которых располагаются на стеке, а ссылочные — это типы, экземпляры которых располагаются в куче». Так что перед Вами перевод дюже ветхой, но не утратившей свою востребованость статье Eric-а Lippert-а. Я постарался сделать перевод как дозволено больше читаемым и лёгким для воспринятия на Русском языке, так что он значительно отличается от оригинала по форме, но не по смыслу.

Источник: programmingmaster.ru
Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB