Sobes.tech
Middle

Opowiedz o stosie wywołań i stercie w kontekście pracy aplikacji Android.

sobes.tech AI

Odpowiedź od AI

Stos wywołań to obszar pamięci używany do tymczasowego przechowywania informacji związanych z wywołaniami funkcji/metod. Każde wywołanie tworzy ramkę (Stack Frame), która zawiera:

  • Zmienne lokalne.
  • Argumenty metody.
  • Adres powrotu.

Ramki są dodawane do stosu zgodnie z zasadą LIFO (Last-In, First-Out). Gdy metoda kończy działanie, jej ramka jest usuwana ze stosu.

Heap (stos) to obszar pamięci używany do dynamicznej alokacji obiektów. Obiekty tworzone są za pomocą operatora new i pozostają żywe, dopóki istnieją do nich odwołania. Jeśli odwołań brak, stają się kandydatami do zbierania śmieci (Garbage Collection).

Główne różnice:

Charakterystyka Stos wywołań Heap
Czas życia Krótki (do zakończenia metody) Długi (dopóki istnieją odwołania)
Przydział pamięci Automatyczny Dynamiczny (new)
Zwolnienie pamięci Automatyczne (po zakończeniu metody) Zbiór śmieci
Rozmiar Ograniczony, predefiniowany Elastyczny, zależy od dostępnej pamięci
Typ danych Typy prymitywne, odwołania do obiektów Obiekty

W Androidzie, każdy wątek ma własny stos wywołań, podczas gdy heap jest współdzielony między wszystkimi wątkami aplikacji. Przepełnienie stosu (StackOverflowError) występuje przy zbyt głębokiej rekurencji lub tworzeniu zbyt wielu zmiennych lokalnych. Brak pamięci w heap (OutOfMemoryError) pojawia się, gdy próbujemy zaalokować obiekt, a nie ma wystarczająco wolnego miejsca.

// Przykład użycia stosu i heap

public class Example {
    private int zmiennaInstancji; // W heap jako część obiektu

    public void jakasMetoda(int parametr) { // parametr - na stosie
        int zmiennaLokalna = 10; // zmiennaLokalna - na stosie

        // Obiekt tworzony w heap
        MyObject obj = new MyObject(); // obj (referencja) - na stosie, sam obiekt - w heap

        obj.zrobCos(zmiennaLokalna); // zmiennaLokalna przekazywana przez wartość na stos nowej ramki
    }

    private class MyObject {
        public void zrobCos(int wartosc) { // wartosc - na stosie ramki zrobCos
            // Metoda zagnieżdżona, dodaje nową ramkę do stosu
            innaMetoda();
        }
    }

    private void innaMetoda() {
        // Ta metoda tworzy nową ramkę na stosie
    }
}