Що і де знаходяться стек і купа?

Книги на мовах програмування пояснюють, що типи значень створюються в стеку, а посилальні типи створюються в купі, не пояснюючи, що це за дві речі. Я не прочитав чіткого пояснення цього. Я розумію, що таке стек. але,

  • де і що вони (фізично в реальному комп'ютерної пам'яті)?
  • Якою мірою вони контролюються операційною системою або мовою?
  • Який їхній обсяг?
  • Що визначає розмір кожного з них?
  • Що робить швидше?
7380
17 сент. заданий mattshane 17 сент. 2008-09-17 07:18 '08 в 7:18 2008-09-17 7:18
@ 25 відповідей

Стек - це пам'ять, відкладена в якості простору схрестити для потоку виконання. Коли викликається функція, блок зарезервований у верхній частині стека для локальних змінних і деяких облікових даних. Коли ця функція повертається, блок стає невживаних і може використовуватися при наступному виклику функції. Стек завжди зарезервований в порядку LIFO (останній в першому порядку); найостанніший зарезервований блок завжди є наступним блоком, який повинен бути звільнений. Це спрощує відстеження стека; звільнення блоку з стека є не більше ніж коригуванням одного покажчика.

Купа - це пам'ять, виділена для динамічного розподілу. На відміну від стека, немає ніякого примусового шаблону для розподілу і звільнення блоків з купи; ви можете виділити блок в будь-який час і звільнити його в будь-який час. Це значно ускладнює відстеження того, які частини купи розподілені або звільнені в будь-який момент часу; існує безліч параметрів купчастих розподільників для настройки продуктивності купи для різних шаблонів використання.

Кожен потік отримує стек, в той час як для програми зазвичай використовується тільки одна купа (хоча не рідкість мати кілька куп для різних типів проживання).

Щоб відповісти на ваші запитання прямо:

Якою мірою вони контролюються операційною системою або мовою?

ОС виділяє стек для кожного потоку системного рівня при створенні потоку. Зазвичай ОС викликається середовищем виконання мови для виділення купи для додатка.

Який їхній обсяг?

Стек прикріплюється до потоку, тому, коли потік виходить з стека, виправляється. Купа зазвичай виділяється під час запуску програми під час виконання і повертається після виходу програми (технічного процесу).

Що визначає розмір кожного з них?

Розмір стека встановлюється при створенні потоку. Розмір купи задається під час запуску програми, але може збільшуватися в міру необхідності (розподільник запитує більше пам'яті з операційної системи).

Що робить швидше?

Стек швидше, тому що шаблон доступу робить тривіальним виділення і звільнення пам'яті від нього (покажчик / ціле просто збільшується або зменшується), а купа має набагато більш складну бухгалтерську звітність, пов'язану з розподілом або звільненням. Крім того, кожен байт в стеці часто використовується повторно, що означає, що він має тенденцію відображатися в кеш процесора, що робить його дуже швидким. Ще одним хітом продуктивності для купи є те, що купа, що є головним чином глобальним ресурсом, як правило, повинна бути многопотоковой безпекою, тобто Кожне розподіл і звільнення повинно бути - як правило, синхронізоване з "усіма" іншими зверненнями купи в програмі.

Чітка демонстрація: 2019

5436
17 сент. відповідь дан Jeff Hill 17 сент. 2008-09-17 07:52 '08 о 7:52 2008-09-17 7:52

Stack

  • Зберігається в оперативній пам'яті комп'ютера, як купа.
  • Змінні, створені в стеці, вийдуть з області дії і автоматично звільняться.
  • Набагато швидше виділяти в порівнянні зі змінними в купі.
  • Реалізовано з фактичною структурою даних стека.
  • Зберігає локальні дані, повертає адреси, використовувані для передачі параметрів.
  • Може мати переповнення стека, коли використовується занадто велика частина стека (в основному з нескінченної або занадто глибокої рекурсії, дуже великих розподілів).
  • Дані, створені в стеці, можуть використовуватися без покажчиків.
  • Ви використовували б стек, якби точно знали, скільки даних вам потрібно виділити перед компіляцією, і воно не дуже велике.
  • Зазвичай максимальний розмір вже визначено, коли запускається ваша програма.

Heap:

border=0
  • Зберігається в оперативній пам'яті комп'ютера так само, як і стек.
  • В С ++ змінні в купі повинні бути знищені вручну і ніколи не випадають з області видимості. Дані звільняються за допомогою delete , delete[] або free .
  • Повільніше виділяти в порівнянні зі змінними в стеці.
  • Використовується на вимогу для виділення блоку даних для використання програмою.
  • Може мати фрагментацію, коли є багато розподілів і звільнень.
  • В С ++ чи C дані, створені в купі, будуть вказані покажчиками і виділені відповідно new або malloc .
  • Може мати відмова в розподілі, якщо потрібно виділення невеликої кількості буфера.
  • Ви б використовували купу, якщо не знаєте точно, скільки даних вам буде потрібно під час виконання або якщо вам потрібно виділити багато даних.
  • Відповідальний за витік пам'яті.

приклад:

2164
17 сент. відповідь дан Brian R. Bondy 17 сент. 2008-09-17 07:20 '08 о 7:20 2008-09-17 7:20

Найбільш важливим моментом є те, що купа і стек є загальні терміни для способів виділення пам'яті. Вони можуть бути реалізовані по-різному, і ці терміни застосовні до основних понять.

  • У стеці елементів елементи розташовуються один над одним в тому порядку, в якому вони були там розміщені, і ви можете видалити тільки верхню частину (без перекидання всієї речі).

    2019

1294
19 марта '09 в 17:38 2009-03-19 17:38 відповідь дан thomasrutter 19 березня '09 о 17:38 2009-03-19 17:38

(Я перемістив цей відповідь з іншого питання, який був більш-менш обманом цього.)

Відповідь на ваше запитання специфічний для реалізації і може відрізнятися в різних компіляторах і архітектурі процесорів. Однак це спрощене пояснення.

  • Обидва стека і купа є областями пам'яті, виділеними з базової операційної системи (часто віртуальна пам'ять, яка за запитом відображається в фізичну пам'ять).
  • У багатопотокової середовищі кожен потік буде мати свій власний повністю незалежний стек, але вони будуть розділяти купу. Паралельний доступ повинен контролюватися в купі і неможливий в стеці.

купа

  • Купа містить пов'язаний список використовуваних і вільних блоків. Нові розподілу в купі (на new або malloc ) задовольняються шляхом створення відповідного блоку з одного з вільних блоків. Це вимагає оновлення списку блоків в купі. Ця метаінформація про блоках в купі також зберігається в купі часто в невеликій області безпосередньо перед кожним блоком.
  • У міру зростання купи нові блоки часто виділяються з нижніх адрес в сторону більш високих адрес. Таким чином, ви можете думати про купу як купі блоків пам'яті, які ростуть в розмірі в міру виділення пам'яті. Якщо купа занадто мала для розподілу, розмір часто може бути збільшений за рахунок придбання більшого обсягу пам'яті з базової операційної системи.
  • Виділення і звільнення багатьох невеликих блоків може залишити купу в стані, в якому є багато невеликих вільних блоків, що перемежовуються між використовуваними блоками. Запит на виділення великого блоку може потерпіти невдачу, тому що ні один з вільних блоків не є достатньо великим, щоб задовольнити запит на розподіл, навіть якщо об'єднаний розмір вільних блоків може бути досить великим. Це називається фрагментацією купи.
  • Коли використовується блок, суміжний з вільним блоком, звільняється, новий вільний блок може бути об'єднаний з суміжних вільним блоком для створення більшого вільного блоку, ефективно зменшує фрагментацію купи.

2019

681
31 июля '09 в 18:54 2009-07-31 18:54 відповідь дан Martin Liversage 31 липня '09 о 18:54 2009-07-31 18:54

У наступному коді С #

Разница между распределением памяти стек и кучи "timmurphy.org