Sobes.tech
Middle

Beszéljen az Android alkalmazások működésének kontextusában a hívásveremről és a heapről.

sobes.tech MI

Válasz az MI-től

A hívási verem egy memória terület, amely ideiglenesen tárolja a függvény/módszer hívásokkal kapcsolatos információkat. Minden hívás létrehoz egy Stack Frame-et (verem keret), amely tartalmazza:

  • Lokális változók.
  • A módszer argumentumai.
  • Visszatérési cím.

A keretek a LIFO (Last-In, First-Out) elv szerint kerülnek a verembe. Amikor egy módszer befejeződik, a hozzá tartozó keret eltávolításra kerül.

A heap (halom) egy memória terület, amelyet az objektumok dinamikus allokációjára használnak. Az objektumokat a new operátorral hozzák létre, és addig élnek, amíg vannak rájuk hivatkozások. Ha nincsenek, akkor a szemétgyűjtés (Garbage Collection) jelöltjeivé válnak.

Fő különbségek:

Jellemző Hívási verem Heap
Élettartam Rövid (amíg a módszer be nem fejeződik) Hosszú (amíg vannak hivatkozások)
Memória foglalás Automatikus Dinamikus (new)
Felszabadítás Automatikus (a módszer végén) Szemétgyűjtés
Méret Korlátozott, előre meghatározott Rugalmas, a rendelkezésre álló memória függvénye
Adattípus Primitív típusok, objektum hivatkozások Objektumok

Androidban minden szál saját hívási veremmel rendelkezik, míg a heap megosztott az összes szál között. A verem túlcsordulás (StackOverflowError) akkor fordul elő, ha túl mély a rekurzió vagy túl sok helyi változót hozunk létre. A heap memóriahiány (OutOfMemoryError) akkor jelentkezik, amikor nem tudunk objektumot foglalni, mert nincs elég szabad hely.

// Példa a verem és a heap használatára

public class Example {
    private int példányváltozó; // Heap-en, mint az objektum része

    public void valamiMetod(int paraméter) { // paraméter - a veremben
        int helyiVáltozó = 10; // helyiVáltozó - a veremben

        // Objektum a heap-en jön létre
        MyObject obj = new MyObject(); // obj (referencia) - a veremben, az objektum - a heap-en

        obj.csinálValamit(helyiVáltozó); // helyiVáltozó érték szerint átadva az új veremi keretbe
    }

    private class MyObject {
        public void csinálValamit(int érték) { // érték - a doSomething veremi keretében
            // Beágyazott módszer, új keret hozzáadása a veremhez
            másMetod();
        }
    }

    private void másMetod() {
        // Ez a módszer új keretet hoz létre a veremben
    }
}