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.
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).
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.
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
- 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ě.
- Manipulace s rámem haldy je nákladnější než manipulace s rámem zásobníku.
- 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.
- 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.
- 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.
- Přístup k času haldy trvá více než jen zásobník.
Srovnávací tabulka
| Parametr | ZÁSOBNÍK | HALDA |
|---|---|---|
| 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áklady | Méně | Více |
| Implementace | Snadný | Tvrdý |
| Doba přístupu | Rychleji | pomaleji |
| Hlavní problém | Nedostatek paměti | Fragmentace paměti |
| Referenční lokalita | Vynikající | Adekvátní |
| Bezpečnost | Vlákno bezpečné, k uloženým datům má přístup pouze vlastník | Není bezpečné pro vlákna, uložená data jsou viditelná pro všechna vlákna |
| Flexibilita | Pevná velikost | Změna velikosti je možná |
| Struktura datových typů | Lineární | Hierarchický |
| Preferováno | V poli je preferováno přidělování statické paměti. | V propojeném seznamu je preferováno přidělení paměti haldy. |
| Velikost | Malá než halda paměti. | Větší než zásobníková paměť. |