Какво и къде са стека и купчината?

Книгите в програмните езици обясняват, че типовете стойности се създават в стека , а типовете справки се създават в купчината , без да се обяснява какво представляват тези две неща. Не съм чел ясно обяснение за това. Разбирам какво е стак. Въпреки това,

  • къде и какви са те (физически в реална компютърна памет)?
  • До каква степен те се контролират от операционната система или езика?
  • Какъв е техният обем?
  • Какво определя размера на всяка от тях?
  • Какво прави по-бързо?
7380
17 сент. комплект матшане 17 сеп . 2008-09-17 07:18 '08 в 7:18 am 2008-09-17 07:18
@ 25 отговора

Стекът е памет, отделена като пространство за надраскване за нишка на изпълнение. Когато се извика функция, блокът е резервиран в горната част на стека за локални променливи и някои идентификационни данни. Когато тази функция се върне, блокът се използва неизползван и може да се използва при следващото извикване на функцията. Стекът винаги е запазен по реда на LIFO (последният в първия ред); последният запазен блок винаги е следващият блок, който трябва да бъде освободен. Това улеснява проследяването на стека; освобождаването на блок от стека не е нищо повече от едно регулиране на показалеца.

Купчината е памет, отделена за динамично разпределение. За разлика от стека, няма принуден шаблон за разпределяне и освобождаване на блокове от куп; Можете да изберете блок по всяко време и да го освободите по всяко време. Това прави много трудно да се проследи кои части от купчината се разпространяват или освобождават по всяко време; Има много специализирани дистрибутори за настройка на производителността на купчина за различни модели на използване.

Всяка нишка получава стек, докато за приложение обикновено се използва само една купчина (въпреки че не е необичайно да има няколко купчини за различни типове разположение).

За да отговорите директно на въпросите си:

До каква степен те се контролират от операционната система или езика?

OS създава стек за всяка нишка на ниво система при създаването на нишка. Обикновено операционната система се извиква от средата за изпълнение на езика, за да разпредели куп за приложение.

Какъв е техният обем?

Стекът е прикрепен към нишката, така че когато нишката излезе от стека, тя се коригира. Купчина обикновено се разпределя, когато приложението се стартира по време на изпълнение и се връща след излизане от приложението (техническия процес).

Какво определя размера на всяка от тях?

Размерът на стека се задава при създаването на нишка. Размерът на купчината се задава, когато приложението се стартира, но може да се увеличи, ако е необходимо (разпределителят изисква повече памет от операционната система).

Какво прави по-бързо?

Стекът е по-бърз, защото моделът на достъп го прави тривиално да разпределя и освобождава памет от него (показалеца / цяло число просто нараства или се свива), а купата има много по-сложни финансови отчети, свързани с разпределението или освобождаването. В допълнение, всеки байт в стека често се използва повторно, което означава, че има тенденция да се показва в кеша на процесора, което го прави много бързо. Друг хит на производителността на куп е, че купчината, която е главно глобален ресурс, обикновено трябва да бъде многопоточна, т.е. Всяка дистрибуция и съобщение трябва да бъдат - като правило, синхронизирани с "всички" други извиквания на купчината в програмата.

Ясна демонстрация: 2019

5436
17 сент. Отговорът е даден Джеф Хил 17 сеп. 2008-09-17 07:52 '08 в 7:52 am 2008-09-17 07:52

купчина

  • Запазено в RAM на компютъра, като куп.
  • Променливите, създадени в стека, излизат извън обхвата и се освобождават автоматично.
  • Много по-бързо се разпределят в сравнение с променливите в купчината.
  • Реализирана с действителна структура данни за стека.
  • Запазва локални данни, връща адреси, използвани за предаване на параметри.
  • Може да има препълване на стека, когато се използва прекалено голяма част от стека (най-вече от безкрайна или твърде дълбока рекурсия, много големи дистрибуции).
  • Данните, създадени в стека, могат да се използват без указатели.
  • Бихте използвали стека, ако знаете точно колко данни трябва да разпределите преди компилирането и не е твърде голямо.
  • Обикновено максималният размер вече е определен при стартиране на програмата.

Heap:

border=0
  • Съхранява се в паметта на компютъра по същия начин като стека.
  • В C ++ променливите в купчината трябва да бъдат ръчно унищожени и никога да не излизат от обхвата. Данните се освобождават с delete , delete[] или free .
  • Той е по-бавен за разпределяне в сравнение с променливите в стека.
  • Използва се при поискване за разпределяне на блок данни за използване от програмата.
  • Може да има фрагментация, когато има много разпределения и изключения.
  • В C ++ или C данните, създадени върху купчината, ще бъдат указани чрез указатели и съответно разпределени за new или malloc .
  • Може да не се разпространи, ако се изисква твърде много буфер.
  • Вие ще използвате куп, ако не знаете точно колко данни ви трябват по време на изпълнение или ако трябва да разпределите много данни.
  • Отговаря за изтичане на паметта.

например:

2164
17 сент. Отговорът е даден от Брайън Р. Бонди 17 сеп. 2008-09-17 07:20 '08 в 7:20 2008-09-17 07: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 юли 2009 в 18:54 2009-07-31 18:54

В следния код C #

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

и тук:

Создание объектов в стеке и куче

Эта статья является источником изображения выше: шесть важных понятий.NET: стек, куча, типы значений, ссылочные типы, бокс и распаковка - CodeProject