C# Стек и Куча | Stack and Heap | Часть 2

Поделиться
HTML-код
  • Опубликовано: 15 июл 2024
  • Это вторая часть серии роликов посвященных работе памяти в .NET. В данном видео мы рассмотрим работу стека и кучи более детально. Будет интересно :)
    Ссылка на первую часть: • C# Стек и Куча | Stack...
    Ссылка на третью часть: • C# Сборщик Мусора | Ga...
    Telegram канал: t.me/codaza
    На кофе ☕️: pay.cloudtips.ru/p/179d0532
    Patreon: / codaza
    Boosty: boosty.to/codaza
    0:00 - Начало
    0:42 - Копирование данных в стеке
    2:34 - Копирование данных в куче
    4:51 - Производительность стека
    8:00 - Ссылочные типы
    10:59 - Технические характеристики стека и кучи
    13:59 - Завершение
    #csharp #стек #куча #stack #heap #stackvsheap

Комментарии • 99

  • @codaza-channel
    @codaza-channel  3 года назад +12

    Удобная навигация по видео :)
    0:00 - Начало
    0:42 - Копирование данных в стеке
    2:34 - Копирование данных в куче
    4:51 - Производительность стека
    8:00 - Ссылочные типы
    10:59 - Технические характеристики стека и кучи
    13:59 - Завершение

    • @Andrew_Moryakov
      @Andrew_Moryakov 2 года назад

      Здравствуйте! В какой программе вы делаете такую инфографика?

    • @codaza-channel
      @codaza-channel  2 года назад

      Здравствуйте! В PowerPoint.

  • @SnakeJek777
    @SnakeJek777 2 года назад +25

    Лучшее объяснение что я когда либо видел по данному вопросу. Спасибо автору! Рад был бы увидеть ссылки на источники для самостоятельного изучения

    • @codaza-channel
      @codaza-channel  2 года назад +1

      Рад, что информация оказалась полезной. Для самостоятельного изучения, рекомендую первоисточник от Microsoft: docs.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals

  • @YaroslavYaroshovets
    @YaroslavYaroshovets 2 года назад +7

    После просмотра видео возникает чувство несправедливости : такая шикарная подача, но так мало подписчиков...

  • @yourownazog8069
    @yourownazog8069 Год назад +5

    Шикарные 2 видео по стеку/куче. Спасибо за визуализацию, очень помогла понять что к чему.

  • @nikapuzach
    @nikapuzach 2 года назад +8

    Потрясающее видео, буквально на первых секундах подписалась. Спасибо за качественный контент!

    • @codaza-channel
      @codaza-channel  2 года назад +2

      Пожалуйста 🙂 Вам спасибо за комментарий и подписку. Очень рад, что контент нравится!

  • @evan_kirk
    @evan_kirk 10 месяцев назад +1

    Шикарное объяснение и разъяснение! Низкий поклон автору

  • @user-bt4zh3rv3i
    @user-bt4zh3rv3i 10 месяцев назад +1

    Прекрасные видео! Дает 100% понимание сути стека, кучи, и их взаимоотношений. Спасибо!!!!

  • @ilya_dikushnikov
    @ilya_dikushnikov Год назад +1

    Бедный Винни Пух

  • @gamerwithoutchannel9721
    @gamerwithoutchannel9721 Год назад +1

    благодаря этим визуализациям и подаче , я смог за 10минут написать пример из видео для структуры и класса и на практике узнать как эти два типа друг от друга отличаются , спасибо!

  • @alex.artechtattoo
    @alex.artechtattoo 2 года назад +2

    Жаль, что с Винни-Пухом так вышло.. Контент отличный!

  • @essentia9
    @essentia9 4 дня назад

    Можно было добавить еще один важный момент в примере с игрушками. Даже если в PlayWithToy передать toy по значению (не по ссылке) и закомментировать 19 строчку кода(создание нового объекта Toy на heap), то CreateToy вернет Пятачка.

  • @user-nm1ld5bb8l
    @user-nm1ld5bb8l 3 месяца назад

    супер понятный ролик!

  • @nokia_n-gage
    @nokia_n-gage 2 года назад +1

    Супер объяснение!

  • @drovss_game
    @drovss_game 2 года назад +2

    Очень интересно и понятно описано)

  • @iraklidavitaia
    @iraklidavitaia 2 года назад +1

    Супер! Спасибо

  • @johndoe4016qweasd
    @johndoe4016qweasd 2 года назад +1

    Спасибо!

  • @arthurandreev709
    @arthurandreev709 Год назад

    Спасибо, ты сделал мой день!

  • @kl45gp
    @kl45gp 2 года назад

    супер

  • @alexeylobankov
    @alexeylobankov Год назад +1

    Отличное видео, все очень наглядно. Лайк, подписка!

  • @antonpylypenko8233
    @antonpylypenko8233 Год назад

    Шикарні відео! Дуже дякую!)

  • @sergeymigel4680
    @sergeymigel4680 Год назад

    красава

  • @slevinsaint9284
    @slevinsaint9284 2 года назад +1

    Отличные уроки! Лайк, шер, подписка - однозначно!

  • @ashotmanukyan8530
    @ashotmanukyan8530 Год назад

    спасибо за детальное объяснение материала + ещё и визуализация. Наконец-то понял как всё работает. Автору респект!

  • @Bankai_Kitetsu
    @Bankai_Kitetsu 6 месяцев назад

    Спасибо большое за ваш труд! Очень помогло))

  • @glukh0v_d1ma
    @glukh0v_d1ma Год назад

    лучше любих курсов!!

  • @hargevorgyan
    @hargevorgyan 2 года назад +1

    Слишком идеальный tutor для 3000 подписчиков,желаю удачи !

  • @darkmeg2015
    @darkmeg2015 2 года назад +1

    проорал с POH :)

  • @alinanur5628
    @alinanur5628 2 года назад +2

    Супер объяснение! Очень наглядно и информативно))Спасибо)Ждем новых видео)

    • @codaza-channel
      @codaza-channel  2 года назад

      Алина, спасибо за комментарий. Рад, что ролик оказался информативным! Не забудьте про 3-ю часть (garbage collector) 🙂

    • @alinanur5628
      @alinanur5628 2 года назад +1

      @@codaza-channel Я посмотрела все части))Завтра собеседование))

    • @codaza-channel
      @codaza-channel  2 года назад

      Держу за Вас кулачки 🤞 По работе с памятью, точно не должно быть пробелов 🙂 Кстати, если на собеседовании будут какие-то каверзные вопросы, пишите, обязательно рассмотрим на канале)

  • @shurale85
    @shurale85 2 года назад +6

    Тему асинхронщины будете раскрывать? ) async/await, tpl, valuetask, когда уместно использование асинк операций, а когда нет..

    • @codaza-channel
      @codaza-channel  2 года назад +4

      Если это будет интересно, обязательно поговорим об этом на канале. Вы пока первый, кто попросил об этом 🙂

    • @shurale85
      @shurale85 2 года назад +4

      @@codaza-channel возможно в данном вопросе Вам нужно проявить проактивный подход и все таки раскрыть эту тему. Думаю этим самым ВЫ привлечете еще бОльше посетителей и подписчиков! Спасибо за контент!

  • @user-dn8vb2xr6b
    @user-dn8vb2xr6b 2 года назад +3

    винни пуха жалко((

  • @DF-ov1zm
    @DF-ov1zm Год назад +1

    До гигабайтов не дойдёт, размер стэка по дефолт - 1мб 😂 а дальше стэковерфлоу эксепшен. И стэк поинтер - это не совсем ссылка, по крайней мере не в памяти, это специальный регистр SP в процессоре

  • @user-su7sk3bk1r
    @user-su7sk3bk1r 2 года назад

    Автор сделай пожалуйста видео про CLR в своем стиле, будет интересно

  • @andrewshpik6220
    @andrewshpik6220 2 года назад +5

    Здравствуйте, отличные видео, спасибо за ваш труд.
    Из видео узнал про POH, возможно у вас получится доступно объяснить подробнее про эту часть Heap в отдельном видео?

    • @codaza-channel
      @codaza-channel  2 года назад +2

      Благодарю за положительный комментарий. Если тема будет интересна, я думаю мы сможем поговорить об этом в отдельном ролике 🙂

    • @andrewshpik6220
      @andrewshpik6220 2 года назад +5

      @@codaza-channel конечно, будете первым, кто в Руском сегменте объяснил это новшество:)

  • @user-bz5kg2yw7m
    @user-bz5kg2yw7m 2 года назад +2

    Спасибо большое за видео! Очень интересно и доходчиво. Скажите, пожалуйста, как конкретно отрабатывает сборщик мусора в стеке на примере вашего метода (2:17)? Если из стека мы берём сверху, то сначала должна удалится переменная orange и потом мы сможем сделать возврат значения переменной apple, или return apple не зависит от наличия в стеке переменной orange? И ещё: удаляется стек фрейм целиком или пошагово по одной переменной, в том порядке как и помещались переменные?

    • @codaza-channel
      @codaza-channel  2 года назад +5

      Екатерина, благодарю за отличный вопрос. Прежде всего стоит отметить, что сборщик мусора работает в куче. На стеке нет такого понятия как сборка мусора. Следующий момент, как таковое удаление данных на стеке не производится. Существует так называемый Stack Pointer (или указатель стека), который указывает на вершину стека. После того как метод завершает работу, Stack Pointer сдвигается вниз на значение стек фрейма. Данные в стеке остаются, просто они будут перезаписаны другими данными, когда потребуется выделение памяти на стеке для размещения очередной переменной, например.

  • @Console.WriteLine
    @Console.WriteLine Год назад

    больше примеров! спасибо

  • @evagor730
    @evagor730 2 года назад +1

    спасибо, классное и наглядное объяснение. Только пох - это pinned object heap (not pick).

    • @codaza-channel
      @codaza-channel  2 года назад

      Благодарю за комментарий. Рад, что информация в ролике оказалась полезной.
      Касательно POH. Подскажите, пожалуйста, на какой временной отметке в ролике Вы услышали "pick"?

    • @evagor730
      @evagor730 2 года назад

      @@codaza-channel дважды прослушала, вроде пик)) ну ладно, может, там было и пиннд)))

    • @slevinsaint9284
      @slevinsaint9284 2 года назад

      @@evagor730 пинд-пинд))

  • @user-tq2om7qu6v
    @user-tq2om7qu6v Год назад

    SOH LOH POH

  • @AlexAlex-ms3bg
    @AlexAlex-ms3bg Год назад

    4:04 - указатель не копируется. В это время создается новый указатель (oranges), который указывает на область памяти NULL. После oranges = apples новому созданному указателю присваивается адрес apples. И он начинает ссылаться на туже область памяти, что и apples

    • @Hennadii_S
      @Hennadii_S 10 месяцев назад

      То есть копируется ссылка. Автор так и сказал.
      И "область памяти NULL"(с) не существует. null - значение предоставляющее пустую ссылку, то есть отсутствие области в памяти, а не какую-то NULL-область.

  • @user-wd4sq4yj8i
    @user-wd4sq4yj8i 7 месяцев назад

    Хорошее видео, но звук перехода с одного раздела на другой очень резкий и бьёт по ушам

  • @Stalker_911
    @Stalker_911 2 года назад +2

    Что будет с Винни Пухом ? Нечего хорошего. Он будет уничтожен!

    • @Hennadii_S
      @Hennadii_S 10 месяцев назад +1

      На самом деле не будет. Мы просто потеряем на него ссылку. И если в процессе будет вызван Garbage Collector, то он пометит Винни как свободную память. И, возможно, в дальнейшем "свободная" память будет заполнена новыми данными.

  • @shurale85
    @shurale85 2 года назад

    а как будет выглядеть размещение переменных в стеке, которые объявлены уже внутри вызываемого метода? К примеру, есть for цикл, внутри которого вызывается некий делегат или поток с лямбда-функцией. Чтобы эти делегаты не шарили общую переменную, которая объявлена в скобках for, нужно объявить доп переменую уже в теле for. Как в этом случаи выделяется память? формируется ли стек фрейм при каждой итерации for? Спасибо!

    • @codaza-channel
      @codaza-channel  2 года назад

      Вы задали очень интересный вопрос. Я отвечу на первую часть вопроса, а по второй попрошу уточнений, так как не совсем понял, что вы имеете ввиду.
      По первой части вопроса. Выделение памяти на стеке происходит очень логично:
      Увидели объявление переменной? Положили значение на стек.
      Переменная находится за пределами области видимости? Убрали значение со стека.
      Таким образом, объявляя переменную внутри цикла For, мы располагаем её значение на стеке (в рамках выделенного стекфрейма). Выполняя очередную итерацию цикла For, предыдущее значение переменной будет удалено со стека, так как будет находиться за пределами области видимости (мы на новой итерации).
      По второй части вопроса. Сначала небольшая ремарка: У каждого потока свой стек. То есть, если у нас будет 10 потоков, у нас будет 10 стеков.
      Вот тут я не понял, что вы имеете ввиду:
      "Чтобы эти делегаты не шарили общую переменную, которая объявлена в скобках for, нужно объявить доп переменую уже в теле for"
      Приведите, пожалуйста, пример кода и тогда, я постараюсь дать более подробный ответ.

  • @user-np4pj9bq7r
    @user-np4pj9bq7r 2 года назад +2

    9:00 - изменение объекта класса возможно при передаче копии ссылки (т.е копия ссылки не запрещает вам менять поля объекта (собственно копия ссылки и не создает копию объекта как некотрым могло бы показаться), как кажется из видео, а мешает только изменить сам объект (допустим переинициализировать)), если не создавать новый объект. Т.е простыми словами копирование ссылки позволяет изменять объект хипа (поменяйте местами строчки кода Playwhittoy) и получите аналогичный результат что и с ref

  • @ilyafilatov1193
    @ilyafilatov1193 2 года назад

    "Сборщик мусора удаляет Пятачка при первой возможности"......

  • @user-kb4ci4gp5o
    @user-kb4ci4gp5o 2 года назад

    на 4:26 можно ли сказать, что мы скопировали именно корзинку с предметами внутри, и передали общее количество предметов в обеих корзинках в Basket ? Для понимания

    • @codaza-channel
      @codaza-channel  2 года назад +1

      Нет, это неверно. Корзинка (Basket) в оперативной памяти всегда одна и количество предметов в ней одно (ItemsCount). А вот ссылок, указывающих на корзинку - две. Сначала была одна ссылка, потом мы её скопировали и получили 2 ссылки, но обе они ссылаются на одну и ту же корзинку.

  • @Hennadii_S
    @Hennadii_S 10 месяцев назад

    Вторая часть уступает первой. Особенно "Технические характеристики" не очень расписаны. Важные детали, например, когда определяется размер выделяемой памяти для переменной и её конкретный тип, почему в результате этих различий куча делает возможным использование полиморфизма. Зато упомянуты не такие фундаментальные детали как local/global и Stack pointer. Хуже всего, что упомянуты совсем в скользь, что делает эту информацию околобесполезной, а если упомянуть на собеседовании, то следующие за этим уточняющие вопросы посадят в лужу. И на практике бесполезно, если знать одни названия. И размер по умолчанию (1мб) тоже какая-то околобесполезная и очень специфическая информация. Лучше совсем такое не упоминать, если не погружаться в детали. SOH-LOH-POH, еще статическую кучу где-то потеряли. Тоже бесполезная информация. Уже лучше бы рассказали тогда про особенности работы GC, почему не очень хорошо создавать "большие" объекты и как они могут приводить к потерям памяти и т.д.
    Короче, слабовато.

  • @user-su7sk3bk1r
    @user-su7sk3bk1r 2 года назад

    Такой вопрос. В структуре объявлено поле типа MyClass. Правильно я понимаю, что когда будет создан экземпляр данной структуры , экземпляр MyClass будет лежать на стеке?

    • @codaza-channel
      @codaza-channel  2 года назад +1

      Нет, MyClass всё еще является ссылочным типом, несмотря на то, что находится внутри структуры. Экземпляр класса MyClass будет размещен в куче, а на стеке будет храниться ссылка на него.

    • @user-su7sk3bk1r
      @user-su7sk3bk1r 2 года назад +1

      @@codaza-channel thank you

  • @shurale85
    @shurale85 2 года назад

    размер стек фрейма определяется типом переменных. наверное есть некая область переменных, из которой они, переменные, попадают в конкретный фрейм. Как определяется эта область (к примеру, под один метод выделяется один фрейм)?

    • @codaza-channel
      @codaza-channel  2 года назад +1

      Стек фрейм определяется при вызове метода. То есть перед началом выполнения тела метода, на стеке определяется место, в котором располагается информация о параметрах метода + служебная информация (например, адреса возвратов). Вследствие чего, происходит смещение указателя стека.

    • @shurale85
      @shurale85 2 года назад

      @@codaza-channel клево, спасибо! еще такой был вопрос, для чего еще придумали кучу, если стек работает быстро. Связано ли это с тем, что стек работать как фифо, а к объекту в куче можно обратиться по адресу? Есть ли ограничения фрейма стека?

    • @codaza-channel
      @codaza-channel  2 года назад +1

      @shurale85 Стек работает быстро, потому что он имеет небольшой размер (1 MB) и работает по принципу LIFO (нужные данные всегда на вершине стека). Куча, в свою очередь, даёт нам память ограниченную лишь ресурсами физической машины и возможность произвольного доступа к данным по адресам в памяти, которые располагаются на стеке. Касательно размера стек фрейма, он ограничен размером стека.

  • @VladisLove-tg5is
    @VladisLove-tg5is 2 года назад

    На 2:31 вы сказали что значение из apples копируется в oranges, но как это происходит, ведь мы можем читать только вершину стека, а apples не на вершине. Допустим мы в конце метода добавим еще int bananas = apples. В бананы скопируется значение яблок, но ведь apples не на вершине стека. Буду рад если уточните этот вопрос)

    • @codaza-channel
      @codaza-channel  2 года назад +2

      Здесь важно понимать, что "Обращение к данным в стеке" и "Извлечение данных из стека" - не одно и тоже. Мы можем производить обращение к данным в стеке без извлечения этих данных из него. Вас же не смущает, что мы можем обратиться к параметрам метода из любого места метода? 🙂
      Извлечение данных из стека применяется при выходе переменной из области видимости (например, при завершении тела цикла). После извлечения данных из стека, они становятся недоступными для дальнейших обращений.

    • @VladisLove-tg5is
      @VladisLove-tg5is 2 года назад +1

      @@codaza-channel спасибо большое, теперь вижу разницу

  • @genjishimada4308
    @genjishimada4308 Год назад

    пяточка жалко... 9:50

  • @amaeton8279
    @amaeton8279 Год назад

    может быть не ref ,а in ? Я прост не слишком шарю.

  • @user-fd2uw6xg6x
    @user-fd2uw6xg6x 2 года назад +1

    А разве Heap неограничен по размерам только для х64, а в х32 потолок таки есть?

    • @codaza-channel
      @codaza-channel  2 года назад

      Да, размер Heap действительно имеет ограничение в 32-разрядных системах и составляет приблизительно 1.5 Гб. Другой вопрос, как часто вам приходится пользоваться 32-разрядными системами в 2022 году? 🙂

    • @user-fd2uw6xg6x
      @user-fd2uw6xg6x 2 года назад

      @@codaza-channel , это да. Просто подумал, что нелишним будет упомянуть про различие в работе с разной архитектурой)

  • @shurale85
    @shurale85 2 года назад

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

    • @codaza-channel
      @codaza-channel  2 года назад

      Если Вы передаете в качестве параметров простые типы (int, bool и т. д.), то в этом точно нет проблемы. Если вы передаёте структуры, то тут нужно рассматривать каждый случай индивидуально, так как даже небольшие структуры передаваемые по значению, но часто, могут создавать проблемы производительности.

  • @phello57
    @phello57 2 года назад +2

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

    • @codaza-channel
      @codaza-channel  2 года назад +1

      Артём, спасибо за вопрос. В .NET существует так называемая Common Language Runtime (англ. CLR - общеязыковая исполняющая среда). Не вдаваясь во все сложности, можно сказать, что CLR это мини операционная система, которая много чего умеет и всегда находится рядом с вашей программой написанной на C#. Именно CLR принимает решение о том, где данные будут расположены - на стеке или в куче.

    • @phello57
      @phello57 2 года назад

      @@codaza-channel Cпасибо за ответ! А скажите пожалуйста, на основании чего идет выбор использовать стек или кучу?

    • @codaza-channel
      @codaza-channel  2 года назад

      Как раз об этом мы подробно говорим в роликах, посвященных работе памяти 😊 Если очень-очень коротко: Значимые типы располагаются на стеке, а ссылочные в куче. Это не всегда так, но для quick start самое лучшее определение. Еще важно понимать, что стек - быстрый, а куча - медленная. Поэтому это имеет свое влияние на производительность.
      Если вы совсем-совсем новичок, я бы рекомендовал вам вернуться к вопросам работы с памятью позже. Не забивайте себе голову этими вещами сейчас. В начале пути лучше сосредоточиться на синтаксисе языка, попробовать что-то сделать самостоятельно (хотя бы калькулятор), повыводить что-нибудь на консоль и т. д.
      Вы почувствуете, когда придёт время разбираться со стеком и кучей 😉

    • @phat80
      @phat80 2 года назад

      Чтобы понять в принципе, что такое стек и куча, а не как она работает в C#, советую начать с самого обычного C. Там придется вручную управлять памятью и через этот процесс можно лучше понять, что вообще происходит в памяти в любой программе на любом языке. Просто в таких языках как C# этот процесс частично происходит под капотом, в C все открыто и наглядно, более того там без понимания принципов работы с памятью - никак.

    • @phello57
      @phello57 2 года назад

      @@phat80 спасибо за совет, так и поступлю :)

  • @vladoss4643
    @vladoss4643 Год назад

    А насчёт копирования данных в куче вопрос. А как тогда сделать, чтобы копировались сами данные, а не ссылки на них?

  • @Brometey
    @Brometey Год назад +1

    Здравствуйте, могу бесплатно обрабатывать ваш голос эквализатором, чтоб его было слышно лучше, так как это в моих интересах. Напишите мне!

    • @codaza-channel
      @codaza-channel  Год назад

      Здравствуйте! Благодарю за предложенную помощь. В последних роликах на канале звук более ровный 🙂

    • @Brometey
      @Brometey Год назад +1

      @@codaza-channel Хорошо, но предложение будет в силе ! Спасибо за простую подачу достаточно ёмкого и сложного материала.

    • @codaza-channel
      @codaza-channel  Год назад

      💙

  • @user-vh5xv3sx1y
    @user-vh5xv3sx1y Год назад

    Жаль, конечно, этого винни пуха

  • @user-cn6bz6ex5u
    @user-cn6bz6ex5u 10 месяцев назад

    Музыка ужасная. Скулы сводит. Урок хорош.

  • @pervertin
    @pervertin 4 месяца назад

    9:55 Пяточка жалко(