Sobes.tech
Middle

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
    }
}