Rozprávajte o zásobníku volaní a halde v kontexte práce s Android aplikáciami.
sobes.tech AI
Odpoveď od AI
Zásobník volaní je oblasť pamäte používaná na dočasné uloženie informácií súvisiacich s volaniami funkcií/metód. Každé volanie vytvára rám (Stack Frame), ktorý obsahuje:
- Lokálne premenné.
- Argumenty metódy.
- Adresu návratu.
Rámy sa pridávajú do zásobníka podľa princípu LIFO (Last-In, First-Out). Keď sa metóda ukončí, jej rám sa odstráni zo zásobníka.
Heap (hromada) je oblasť pamäte používaná na dynamické prideľovanie objektov. Objekty sa vytvárajú pomocou operátora new a žijú dovtedy, kým na ne existujú odkazy. Ak odkazy neexistujú, stávajú sa kandidátmi na zber odpadu (Garbage Collection).
Hlavné rozdiely:
| Charakteristika | Zásobník volaní | Hromada |
|---|---|---|
| Životnosť | Krátka (do ukončenia metódy) | Dlhodobá (kým existujú odkazy) |
| Pridelenie pamäte | Automatické | Dynamické (new) |
| Uvoľnenie pamäte | Automatické (po ukončení metódy) | Zber odpadu |
| Veľkosť | Obmedzená, preddefinovaná | Flexibilná, závisí od dostupnej pamäte |
| Typ dát | Primitívne typy, odkazy na objekty | Objekty |
V Androide má každý vlákno svoj vlastný zásobník volaní, zatiaľ čo hromada je zdieľaná medzi všetkými vláknami aplikácie. Pretečenie zásobníka (StackOverflowError) nastáva pri príliš hlbokej rekurzii alebo vytvorení príliš veľa lokálnych premenných. Nedostatok pamäte v hromade (OutOfMemoryError) nastáva pri pokuse alokovať objekt, keď v hromade nie je dostatok voľného miesta.
// Príklad použitia zásobníka a hromady
public class Example {
private int instanceVariable; // Nachádza sa v hromade ako časť objektu
public void someMethod(int parameter) { // parameter - na zásobníku
int localVariable = 10; // localVariable - na zásobníku
// Objekt sa vytvára v hromade
MyObject obj = new MyObject(); // obj (odkaz) - na zásobníku, samotný objekt - v hromade
obj.doSomething(localVariable); // localVariable sa prenáša hodnotou na zásobník nového rámca
}
private class MyObject {
public void doSomething(int value) { // value - na zásobníku rámca doSomething
// Vnorená metóda, pridáva nový rám do zásobníka
anotherMethod();
}
}
private void anotherMethod() {
// Táto metóda vytvára nový rám do zásobníka
}
}