logo

Zásobník vs alokace paměti haldy

Paměť v programu C/C++/Java může být alokována na zásobníku nebo na hromadě.
Předpoklad: Rozložení paměti programu C .


Přidělení zásobníku: Alokace probíhá na souvislých blocích paměti. Říkáme tomu alokace paměti zásobníku, protože k alokaci dochází v zásobníku volání funkce. Velikost paměti, která má být přidělena, je kompilátoru známa a kdykoli je zavolána funkce, její proměnné získají přidělenou paměť na zásobníku. A kdykoli je volání funkce ukončeno, paměť pro proměnné je uvolněna. To vše se děje pomocí některých předdefinovaných rutin v kompilátoru. Programátor se nemusí starat o alokaci paměti a zrušení alokace proměnných zásobníku. Tento druh přidělení paměti je také známý jako dočasné přidělení paměti, protože jakmile metoda dokončí své provádění, všechna data patřící k této metodě se automaticky vyprázdní ze zásobníku. To znamená, že jakákoli hodnota uložená ve schématu paměti zásobníku je přístupná, dokud metoda nedokončí své provedení a je aktuálně ve stavu běhu.



proč řetězec neměnný v java

Klíčové body:

  • Jedná se o dočasné schéma alokace paměti, kde jsou datové členy přístupné pouze v případě, že je aktuálně spuštěna metoda(), která je obsahovala.
  • Automaticky přiděluje nebo odděluje paměť, jakmile příslušná metoda dokončí své provádění.
  • Obdržíme odpovídající chybu Java. lang. StackOverFlowError podle JVM , Pokud je zásobníková paměť zcela zaplněna.
  • Přidělení paměti zásobníku je považováno za bezpečnější ve srovnání s přidělením paměti haldy, protože k uloženým datům má přístup pouze vlákno vlastníka.
  • Alokace a zrušení alokace paměti jsou rychlejší ve srovnání s alokací paměti haldy.
  • Zásobníková paměť má méně úložného prostoru ve srovnání s pamětí Heap.
C++
int main() {  // All these variables get memory  // allocated on stack  int a;  int b[10];  int n = 20;  int c[n]; }>


Přidělení haldy: Paměť je alokována během provádění instrukcí napsaných programátory. Všimněte si, že název haldy nemá nic společného s únik paměti se může stát v programu.



Alokace paměti haldy je dále rozdělena do tří kategorií: - Tyto tři kategorie nám pomáhají upřednostňovat data (objekty), která mají být uložena v paměti haldy nebo v Odvoz odpadků .

čtení ze souboru csv v jazyce Java
  • Mladá generace - Je to část paměti, kde jsou všechna nová data (objekty) vytvořena pro přidělení prostoru, a kdykoli je tato paměť zcela zaplněna, zbytek dat se uloží do kolekce Garbage collection.
  • Stará nebo vysloužilá generace – Toto je část paměti Heap-memory, která obsahuje starší datové objekty, které se často nepoužívají nebo se nepoužívají vůbec.
  • Stálá generace - Toto je část Heap-memory, která obsahuje metadata JVM pro běhové třídy a aplikační metody.

Klíčové body:

  • Pokud je halda zcela plná, obdržíme odpovídající chybovou zprávu, Jáva. lang.OutOfMemoryError od JVM.
  • Toto schéma přidělování paměti se liší od přidělování prostoru zásobníku, zde není poskytována žádná funkce automatického zrušení přidělování. Abychom mohli efektivně využít paměť, musíme použít sběrač odpadků k odstranění starých nepoužívaných objektů.
  • Doba zpracování (Accessing time) této paměti je poměrně pomalá ve srovnání s Stack-memory.
  • Paměť haldy také není tak bezpečná ve vláknech jako paměť Stack, protože data uložená v paměti haldy jsou viditelná pro všechna vlákna.
  • Velikost paměti haldy je poměrně větší ve srovnání s pamětí zásobníku.
  • Paměť haldy je přístupná nebo existuje, dokud běží celá aplikace (nebo java program).
CPP
int main() {  // This memory for 10 integers  // is allocated on heap.  int *ptr = new int[10]; }>

Kombinovaný příklad obou druhů alokace paměti haldy a zásobníku v jazyce 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; }>
Jáva
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);  } }>
Krajta
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>

Níže jsou uvedeny závěry, ke kterým po analýze výše uvedeného příkladu učiníme:

  • Jakmile zahájíme provádění programu have, všechny run-time třídy jsou uloženy v prostoru paměti Heap.
  • Pak na dalším řádku najdeme metodu main(), která je uložena v zásobníku spolu se všemi svými primitivními (nebo místními) a referenční proměnná Emp typu Emp_detail bude také uložena v zásobníku a bude ukazovat na odpovídající objekt uloženy v paměti haldy.
  • Pak další řádek zavolá parametrizovaný konstruktor Emp(int, String) z main() a také se alokuje na začátek stejného bloku paměti zásobníku. Toto uloží:
    • Odkaz na objekt vyvolaného objektu paměti zásobníku.
    • Primitivní hodnota ( Referenční proměnná argumentu String název_emp bude ukazovat na skutečný řetězec z fondu řetězců do paměti haldy.
  • Potom hlavní metoda znovu zavolá statickou metodu Emp_detail(), pro kterou bude alokace provedena v bloku paměti zásobníku nad předchozím blokem paměti.
  • Referenční proměnná argumentu String název_emp bude ukazovat na skutečný řetězec z fondu řetězců do paměti haldy.
  • Takže pro nově vytvořený objekt Emp typu Emp_detail a všechny proměnné instance budou uloženy v paměti haldy.
  • Referenční proměnná argumentu String název_emp bude ukazovat na skutečný řetězec z fondu řetězců do paměti haldy.

  • Obrazové znázornění, jak je znázorněno na obrázku 1 níže:

    Referenční proměnná argumentu String název_emp bude ukazovat na skutečný řetězec z fondu řetězců do paměti haldy.
  • Obr. 1

    rozdíl v datech v excelu

    Klíčové rozdíly mezi alokací zásobníku a haldy

    1. V zásobníku alokaci a zrušení alokace provádí automaticky kompilátor, zatímco v haldě to musí provést programátor ručně.
    2. Manipulace s rámem haldy je nákladnější než manipulace s rámem zásobníku.
    3. Problém s nedostatkem paměti je pravděpodobnější v zásobníku, zatímco hlavním problémem v paměti haldy je fragmentace.
    4. Přístup k rámcům zásobníku je snazší než rámeček haldy, protože zásobník má malou oblast paměti a je přátelský k vyrovnávací paměti, ale v případě rámců haldy, které jsou rozptýleny v paměti, způsobuje více vynechání mezipaměti.
    5. Zásobník není flexibilní, velikost přidělené paměti nelze změnit, zatímco halda je flexibilní a přidělenou paměť lze změnit.
    6. Přístup k času haldy trvá více než jen zásobník.

    Srovnávací tabulka

    ParametrZÁSOBNÍKHALDA
    ZákladníPaměť je alokována v souvislém bloku.Paměť je alokována v libovolném náhodném pořadí.
    Přidělování a přidělováníAutomaticky podle pokynů kompilátoru.Manuál od programátora.
    NákladyMéněVíce
    ImplementaceSnadnýTvrdý
    Doba přístupuRychlejipomaleji
    Hlavní problémNedostatek pamětiFragmentace paměti
    Referenční lokalitaVynikajícíAdekvátní
    BezpečnostVlákno bezpečné, k uloženým datům má přístup pouze vlastníkNení bezpečné pro vlákna, uložená data jsou viditelná pro všechna vlákna
    FlexibilitaPevná velikostZměna velikosti je možná
    Struktura datových typůLineárníHierarchický
    PreferovánoV poli je preferováno přidělování statické paměti.V propojeném seznamu je preferováno přidělení paměti haldy.
    VelikostMalá než halda paměti.Větší než zásobníková paměť.