logo

Zásobník vs alokácia pamäte haldy

Pamäť v programe C/C++/Java môže byť alokovaná na zásobníku alebo na halde.
Predpoklad: Rozloženie pamäte programu C .


Pridelenie zásobníka: Alokácia prebieha na súvislých blokoch pamäte. Nazývame to alokácia zásobníkovej pamäte, pretože alokácia prebieha v zásobníku volania funkcií. Veľkosť pamäte, ktorá sa má prideliť, je kompilátoru známa a vždy, keď je zavolaná funkcia, jej premenné dostanú pridelenú pamäť v zásobníku. A vždy, keď sa volanie funkcie skončí, pamäť pre premenné sa uvoľní. To všetko sa deje pomocou niektorých preddefinovaných rutín v kompilátore. Programátor sa nemusí starať o alokáciu pamäte a dealokáciu zásobníkových premenných. Tento druh prideľovania pamäte je známy aj ako dočasné prideľovanie pamäte, pretože akonáhle metóda dokončí svoje vykonávanie, všetky dáta patriace tejto metóde sa automaticky vyprázdnia zo zásobníka. To znamená, že akákoľvek hodnota uložená v schéme zásobníkovej pamäte je prístupná, pokiaľ metóda nedokončila svoju realizáciu a je momentálne v spustenom stave.



centos vs rhel

Kľúčové body:

  • Ide o dočasnú schému prideľovania pamäte, kde sú dátové členy prístupné iba vtedy, ak je momentálne spustená metóda(), ktorá ich obsahovala.
  • Automaticky pridelí alebo zruší pridelenie pamäte, akonáhle príslušná metóda dokončí svoju realizáciu.
  • Dostávame zodpovedajúcu chybu Java. lang. StackOverFlowError podľa JVM , Ak je zásobníková pamäť úplne zaplnená.
  • Pridelenie pamäte zásobníka sa považuje za bezpečnejšie v porovnaní s prideľovaním pamäte haldy, pretože k uloženým údajom má prístup iba vlákno vlastníka.
  • Prideľovanie a zrušenie prideľovania pamäte je rýchlejšie v porovnaní s prideľovaním pamäte haldy.
  • Zásobníková pamäť má menej úložného priestoru v porovnaní s pamäťou Heap.
C++
int main() {  // All these variables get memory  // allocated on stack  int a;  int b[10];  int n = 20;  int c[n]; }>


Pridelenie haldy: Pamäť je alokovaná počas vykonávania inštrukcií napísaných programátormi. Všimnite si, že názov halda nemá nič spoločné s únik pamäte sa môže stať v programe.



Pridelenie pamäte haldy je ďalej rozdelené do troch kategórií: - Tieto tri kategórie nám pomáhajú určiť prioritu údajov (objektov), ​​ktoré sa majú uložiť do pamäte haldy alebo do Odvoz odpadu .

čítanie zo súboru csv v jazyku Java
  • Mladá generácia - Je to časť pamäte, kde sú všetky nové údaje (objekty) vytvorené na pridelenie priestoru a vždy, keď je táto pamäť úplne zaplnená, zvyšok údajov sa uloží do zberu odpadu.
  • Stará alebo držaná generácia – Toto je časť Heap-memory, ktorá obsahuje staršie dátové objekty, ktoré sa často nepoužívajú alebo sa nepoužívajú vôbec.
  • Stála generácia - Toto je časť Heap-memory, ktorá obsahuje metadáta JVM pre runtime triedy a aplikačné metódy.

Kľúčové body:

  • Ak je halda úplne plná, dostaneme zodpovedajúce chybové hlásenie, java. lang.OutOfMemoryError od JVM.
  • Táto schéma prideľovania pamäte sa líši od prideľovania priestoru zásobníka, tu nie je poskytovaná žiadna funkcia automatického zrušenia prideľovania. Aby sme mohli efektívne využívať pamäť, musíme použiť zberač odpadu na odstránenie starých nepoužívaných predmetov.
  • Čas spracovania (čas prístupu) tejto pamäte je pomerne pomalý v porovnaní so zásobníkom pamäte.
  • Pamäť haldy tiež nie je taká bezpečná ako pamäť typu Stack, pretože údaje uložené v pamäti haldy sú viditeľné pre všetky vlákna.
  • Veľkosť pamäte haldy je pomerne väčšia v porovnaní s pamäťou zásobníka.
  • Pamäť haldy je prístupná alebo existuje, pokiaľ beží celá aplikácia (alebo java program).
CPP
int main() {  // This memory for 10 integers  // is allocated on heap.  int *ptr = new int[10]; }>

Zmiešaný príklad oboch druhov haldy a zásobníka prideľovania pamäte v jazyku Java:



C++
#include  using namespace std; int main() {  int a = 10; // stored in stack  int* p = new int(); // allocate memory in heap  *p = 10;  delete (p);  p = new int[4]; // array in heap allocation  delete[] p;  p = NULL; // free heap  return 0; }>
Java
class Emp {  int id;  String emp_name;  public Emp(int id, String emp_name) {  this.id = id;  this.emp_name = emp_name;  } } public class Emp_detail {  private static Emp Emp_detail(int id, String emp_name) {  return new Emp(id, emp_name);  }  public static void main(String[] args) {  int id = 21;  String name = 'Maddy';  Emp person_ = null;  person_ = Emp_detail(id, name);  } }>
Python
def main(): a = 10 # stored in stack p = None # declaring p variable p = 10 # allocating memory in heap del p # deleting memory allocation in heap p = [None] * 4 # array in heap allocation p = None # free heap return 0 if __name__ == '__main__': main()>
Javascript
// Define the Emp class with id and emp_name properties class Emp {  constructor(id, emp_name) {  this.id = id; // Initialize id  this.emp_name = emp_name; // Initialize emp_name  } } // Create an instance of the Emp class const person = new Emp(21, 'Maddy'); // Initialize person with id 21 and emp_name 'Maddy' console.log(person); // Output the person object to the console>

Nasledujú závery, ku ktorým urobíme po analýze vyššie uvedeného príkladu:

ako premenovať adresár linux
  • Keď začneme vykonávať program have, všetky run-time triedy sú uložené v priestore pamäte haldy.
  • Potom v ďalšom riadku nájdeme metódu main(), ktorá je uložená v zásobníku spolu so všetkými jej primitívnymi (alebo lokálnymi) a referenčná premenná Emp typu Emp_detail bude tiež uložená v zásobníku a bude ukazovať na zodpovedajúci objekt. uložené v pamäti haldy.
  • Potom nasledujúci riadok zavolá parametrizovaný konštruktor Emp(int, String) z main() a tiež sa pridelí na začiatok rovnakého bloku pamäte zásobníka. Toto uloží:
    • Odkaz na objekt vyvolaného objektu zásobníkovej pamäte.
    • Primitívna hodnota ( Referenčná premenná argumentu String emp_name bude ukazovať na skutočný reťazec z oblasti reťazcov do pamäte haldy.
  • Potom hlavná metóda opäť zavolá statickú metódu Emp_detail(), pre ktorú sa alokácia vykoná v bloku pamäte zásobníka nad predchádzajúcim blokom pamäte.
  • Referenčná premenná argumentu String emp_name bude ukazovať na skutočný reťazec z oblasti reťazcov do pamäte haldy.
  • Takže pre novovytvorený objekt Emp typu Emp_detail a všetky premenné inštancie budú uložené v pamäti haldy.
  • Referenčná premenná argumentu String emp_name bude ukazovať na skutočný reťazec z oblasti reťazcov do pamäte haldy.

  • Obrazové znázornenie, ako je znázornené na obrázku 1 nižšie:

    Referenčná premenná argumentu String emp_name bude ukazovať na skutočný reťazec z oblasti reťazcov do pamäte haldy.
  • Obr.1

    Kľúčové rozdiely medzi pridelením zásobníka a haldy

    1. V zásobníku alokáciu a zrušenie alokácie automaticky vykonáva kompilátor, zatiaľ čo v halde to musí vykonať programátor manuálne.
    2. Manipulácia s rámom haldy je nákladnejšia ako manipulácia so stohovacím rámom.
    3. Problém s nedostatkom pamäte sa pravdepodobnejšie vyskytne v zásobníku, zatiaľ čo hlavným problémom v pamäti haldy je fragmentácia.
    4. Prístup k rámcom zásobníka je jednoduchší ako rámcom haldy, pretože zásobník má malú oblasť pamäte a je priateľský k vyrovnávacej pamäti, ale v prípade rámcov haldy, ktoré sú rozptýlené v pamäti, spôsobuje viac vynechaní vyrovnávacej pamäte.
    5. Zásobník nie je flexibilný, veľkosť pridelenej pamäte sa nedá zmeniť, zatiaľ čo halda je flexibilná a pridelená pamäť sa dá zmeniť.
    6. Prístup k času haldy trvá viac ako zásobník.

    Porovnávacia tabuľka

    ParameterSTOHHEAP
    ZákladnéPamäť je alokovaná v súvislom bloku.Pamäť je prideľovaná v ľubovoľnom náhodnom poradí.
    Alokácia a DealokáciaAutomaticky podľa pokynov kompilátora.Manuál od programátora.
    nákladyMenejViac
    ImplementáciaJednoduchéŤažko
    Čas prístupuRýchlejšiepomalšie
    Hlavný problémNedostatok pamäteFragmentácia pamäte
    Referenčná lokalitaVýborneAdekvátne
    BezpečnosťVlákno bezpečné, k uloženým údajom má prístup iba vlastníkNie je bezpečné pre vlákna, uložené údaje sú viditeľné pre všetky vlákna
    FlexibilitaPevná veľkosťZmena veľkosti je možná
    Štruktúra dátového typuLineárneHierarchický
    PreferovanéV poli je preferovaná alokácia statickej pamäte.V prepojenom zozname sa uprednostňuje alokácia pamäte haldy.
    VeľkosťMalá ako hromada pamäte.Väčšia ako zásobníková pamäť.