Pasakok apie iškvietimų steką ir krūvą Android programų darbo kontekste.
sobes.tech AI
Atsakymas iš AI
Kviečiamas stekas — tai atminties sritis, naudojama laikiniems su funkcijų/metodų iškvietimais susijusios informacijos saugojimui. Kiekvienas iškvietimas sukuria Stack Frame, kuris apima:
- Vietines kintamąsias.
- Metodų argumentus.
- Grąžinimo adresą.
Frame'ai yra pridedami į steką pagal LIFO (Last-In, First-Out) principą. Kai metodas baigiasi, jo frame'as pašalinamas iš steko.
Heap (krepšelis) — tai atminties sritis, naudojama dinamiškai objektų paskirstymui. Objektai kuriami naudojant new operatorių ir gyvena tol, kol jiems yra nuorodų. Jei nuorodų nėra, jie tampa šiukšlių surinkimo (Garbage Collection) kandidatais.
Pagrindiniai skirtumai:
| Savybė | Kviečiamas stekas | Krepšelis |
|---|---|---|
| Gyvavimo laikas | Trumpas (iki metodo pabaigos) | Ilgas (kol yra nuorodų) |
| Atminties paskirstymas | Automatinis | Dinamiškas (new) |
| Atminties išlaisvinimas | Automatinis (po metodo pabaigos) | Šiukšlių surinkimas |
| Dydis | Ribotas, iš anksto nustatytas | Lankstus, priklauso nuo prieinamos atminties |
| Duomenų tipas | Primityvūs tipai, nuorodos į objektus | Objektai |
Android'e kiekvienas srautas turi savo atskirą kviečiamą steką, o krepšelis yra bendras visiems srautams. Perpildymas (StackOverflowError) įvyksta per daug gilių rekursijų arba kuriant per daug vietinių kintamųjų. Atminties stygius krepšelyje (OutOfMemoryError) įvyksta bandant paskirstyti objektą, kai nėra pakankamai laisvos vietos.
// Pavyzdys, kaip naudoti steką ir krepšelį
public class Example {
private int instanceVariable; // esantis krepšelyje kaip objekto dalis
public void someMethod(int parameter) { // parameter — steke
int localVariable = 10; // localVariable — steke
// Objekto kūrimas krepšelyje
MyObject obj = new MyObject(); // obj (nuoroda) — steke, pats objektas — krepšelyje
obj.doSomething(localVariable); // localVariable perduodama reikšme į naujo fono steką
}
private class MyObject {
public void doSomething(int value) { // value — doSomething steko fone
// Vidinis metodas, prideda naują frame'ą į steką
anotherMethod();
}
}
private void anotherMethod() {
// Šis metodas sukuria naują frame'ą steke
}
}