Подтвердить что ты не робот

Стек против кучи в .NET.

В вашем реальном опыте программирования, как это знание STACK и HEAP действительно спасло вас в реальной жизни? Любая история из окопов? Или эта концепция хороша для заполнения книг по программированию и хороша для теории?

4b9b3361

Ответ 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

следовательно, два ссылочных типа, указывающих на один и тот же тип значения. Кошмар был предотвращен.