Стек против кучи в .NET.
В вашем реальном опыте программирования, как это знание STACK и HEAP действительно спасло вас в реальной жизни? Любая история из окопов? Или эта концепция хороша для заполнения книг по программированию и хороша для теории?
Ответы
Ответ 1
Для меня это разница между тем, чтобы быть "разработчиком/программистом" и "мастером". Любой может научиться писать код и видеть, как вещи "магически происходят" для вас, не зная, почему и как. Чтобы действительно быть ценным в том, что вы делаете, я думаю, что очень важно узнать как можно больше о Framework, который вы используете. Помните, что это не просто язык, это основа, которую вы используете для создания наилучшего приложения для ваших способностей.
Я анализировал много дампов памяти на протяжении многих лет и нашел это чрезвычайно полезным, зная внутренности и различия между ними. Большинство из них были условиями OutOfMemory и нестабильными приложениями. Это знание абсолютно необходимо использовать WinDbg при просмотре дампов. При исследовании дампа памяти, зная, как распределена память между процессом kernel/user-mode и CLR, вы можете, по крайней мере, сказать вам, с чего начать анализ.
Например, возьмите случай OOM:
Выделенная память, которую вы видите в размерах кучи, рабочем наборе, частной памяти, общей памяти, виртуальной памяти, фиксированной памяти, ручках и потоках, может быть большим показателем того, с чего начать.
Здесь около 8 разных куч, которые использует CLR:
- Куча загрузчика: содержит структуры CLR и систему типов
- Высокочастотная куча: статика, Таблицы методов, FieldDescs, карта интерфейса
- Низкочастотная куча: таблицы EEClass, ClassLoader и таблицы поиска
- Stub Heap: заглушки для CAS, COM-обертки, P/Invoke
- Большая куча объектов: распределения памяти, для которых требуется более 85 тыс. байт.
- GC Heap: выделенная пользователем куча памяти, приватная для приложения
- JIT Code Heap: память, выделенная mscoreee (Execution Engine) и JIT-компилятор для управляемого кода
- Process/Base Heap: interop/неуправляемые распределения, встроенная память и т.д.
Поиск того, что куча имеет высокие распределения, может сказать мне, есть ли у меня фрагментация памяти, утечки управляемой памяти, взаимные/неуправляемые утечки и т.д.
Зная, что у вас есть 1MB (на x86)/4MB (на x64) пространства стека, выделенного для каждого потока, используемого вашим приложением, напоминает мне, что если у меня есть 100 потоков, у вас будет дополнительно 100 МБ использования виртуальной памяти.
У меня был клиент, у которого были проблемы с проблемами с OutOfMemory серверами Citrix, которые были нестабильными и медленными, когда их приложение запускалось на нескольких сеансах. Посмотрев на дамп (у меня не было доступа к серверу), я увидел, что в этом экземпляре приложения используется более 700 потоков! Знание распределения стека потоков позволило мне сопоставить OOM, вызванные использованием высоких потоков.
Короче говоря, из-за того, что я делаю для своей "роли", это бесценное знание. Конечно, даже если вы не отлаживаете отвалы памяти, это никогда не повредит!
Ответ 2
Различие в .NET между семантикой ссылочных типов и типов значений является гораздо более важным понятием.
Лично я никогда не думал о стеке или куче за все мои годы кодирования (только на основе CLR).
Ответ 3
Конечно, полезно понять различие при создании компиляторов.
Вот несколько статей, которые я написал о том, как различные проблемы управления памятью влияют на дизайн и реализацию языка С# и CLR:
http://blogs.msdn.com/ericlippert/archive/tags/Memory+Management/default.aspx
Ответ 4
Я не думаю, что это важно, если вы просто строите средние бизнес-приложения, и я думаю, что большинство программистов .NET.
В книгах, которые я видел, просто упоминается стек и куча, проходя мимо, как будто запоминание этого факта является чем-то монументальным.
Ответ 5
Лично это один из тех немногих технических вопросов, которые я задаю каждому, кого я собираюсь нанять.
Я считаю, что очень важно понять, как использовать платформу .NET(и большинство других языков). Я никогда не нанимаю кого-то, у кого нет четкого понимания использования памяти в стеке против кучи.
Не понимая этого, почти невозможно понять сборщика мусора, понять характеристики производительности .NET и многие другие важные проблемы разработки.
Ответ 6
Важное различие между ссылочными типами и типами значений. Неверно, что "типы значений идут в стеке, ссылочные типы переходят в кучу". Джон Скит написал об этом, и поэтому Эрик Липперт.
Ответ 7
У нас был объект претензии (бизнес-объект), который содержал данные для целого требования. Одним из требований приложения было создание контрольного журнала для каждого значения, измененного пользователем. Для этого, не дважды попав в базу данных, мы будем поддерживать оригинальную структуру заявки в форме и объекте "Искрочный запрос". Объект "Рабочая реклама" будет обновляться, когда пользователь щелкнет "Сохранить", и затем мы сравним свойства Original Entity Entity с соответствующими свойствами Entity Entity Entity, чтобы определить, что изменилось. Однажды мы заметили, что наш метод сравнения никогда не находит разницы. Именно здесь мое понимание стека и кучи спасло мой задний конец (в частности, типы значений по сравнению с ссылочными типами). Поскольку нам нужно было поддерживать копии одного и того же объекта в памяти, разработчик просто создал два объекта
Dim originalClaim As ClaimBE
Dim workingClaim As ClaimBE
затем вызвал метод бизнес-уровня, чтобы вернуть объект претензии и присвоил те же самые требования BE обеим переменным
originalClaim = BLL.GetClaim()
workingClaim = originalClaim
следовательно, два ссылочных типа, указывающих на один и тот же тип значения. Кошмар был предотвращен.