Sobes.tech
Middle

Vorbește despre stiva de apeluri și heap în contextul lucrului cu aplicații Android.

sobes.tech AI

Răspuns de la AI

Stiva de apel este o zonă de memorie utilizată pentru stocarea temporară a informațiilor legate de apelurile funcțiilor/metodelor. Fiecare apel creează un cadru (Stack Frame) care conține:

  • Variabile locale.
  • Argumente ale metodei.
  • Adresa de returnare.

Cramele sunt adăugate în stivă conform principiului LIFO (Last-In, First-Out). Când o metodă se încheie, cadrul său este eliminat din stivă.

Heap-ul (heap) este o zonă de memorie utilizată pentru alocarea dinamică a obiectelor. Obiectele sunt create cu operatorul new și rămân în viață atâta timp cât există referințe către ele. Dacă nu mai există referințe, devin candidați pentru colectarea gunoiului (Garbage Collection).

Diferențele principale:

Caracteristică Stiva de apeluri Heap
Durata de viață Scurtă (până la terminarea metodei) Lungă (atâta timp cât există referințe)
Alocarea memoriei Automată Dinamică (new)
Dezalocarea Automată (la terminarea metodei) Colectarea gunoiului
Dimensiune Limitată, predefinită Flexibilă, depinde de memoria disponibilă
Tip de date Tipuri primitive, referințe la obiecte Obiecte

În Android, fiecare fir de execuție are propria sa stivă de apeluri, în timp ce heap-ul este partajat între toate firele aplicației. Supraîncărcarea stivei (StackOverflowError) apare în cazul recursiei prea profunde sau creării prea multor variabile locale. Lipsa memoriei în heap (OutOfMemoryError) apare atunci când se încearcă alocarea unui obiect fără spațiu liber suficient.

// Exemplu de utilizare a stivei și heap-ului

public class Example {
    private int variabilaDeInstanță; // În heap ca parte a obiectului

    public void someMethod(int parametru) { // parametru - pe stivă
        int variabilăLocală = 10; // variabilăLocală - pe stivă

        // Obiectul este creat în heap
        MyObject obj = new MyObject(); // obj (referință) - pe stivă, obiectul - în heap

        obj.doSomething(variabilăLocală); // variabilăLocală este transmisă prin valoare în noul cadru de pe stivă
    }

    private class MyObject {
        public void doSomething(int valoare) { // valoare - în stiva cadrului doSomething
            // Metodă imbricată, adaugă un nou cadru în stivă
            anotherMethod();
        }
    }

    private void anotherMethod() {
        // Această metodă creează un nou cadru în stivă
    }
}