Fale sobre a pilha de chamadas e o heap no contexto do trabalho de aplicações Android.
sobes.tech IA
Resposta da IA
A pilha de chamadas é uma região de memória usada para armazenar temporariamente informações relacionadas com chamadas de funções/métodos. Cada chamada cria um quadro (Stack Frame) que contém:
- Variáveis locais.
- Argumentos do método.
- Endereço de retorno.
Os quadros são adicionados à pilha segundo o princípio LIFO (Last-In, First-Out). Quando um método termina, o seu quadro é removido da pilha.
O heap (montão) é uma região de memória usada para a alocação dinâmica de objetos. Os objetos são criados com o operador new e permanecem vivos enquanto existirem referências a eles. Se não houver referências, tornam-se candidatos à recolha de lixo (Garbage Collection).
Principais diferenças:
| Característica | Pilha de chamadas | Montão |
|---|---|---|
| Tempo de vida | Curto (até ao término do método) | Longo (enquanto existirem referências) |
| Alocação de memória | Automática | Dinâmica (new) |
| Desalocação | Automática (ao terminar o método) | Recolha de lixo |
| Tamanho | Limitado, predefinido | Flexível, depende da memória disponível |
| Tipo de dados | Tipos primitivos, referências a objetos | Objetos |
Em Android, cada thread tem a sua própria pilha de chamadas, enquanto que o heap é partilhado entre todas as threads da aplicação. O estouro de pilha (StackOverflowError) ocorre por recursão demasiado profunda ou criação excessiva de variáveis locais. A falta de memória no heap (OutOfMemoryError) ocorre ao tentar alocar um objeto quando não há espaço suficiente.
// Exemplo de uso de pilha e heap
public class Exemplo {
private int variavelDeInstancia; // No heap como parte do objeto
public void algumMetodo(int parametro) { // parametro - na pilha
int variavelLocal = 10; // variavelLocal - na pilha
// Objeto criado no heap
MyObject obj = new MyObject(); // obj (referência) - na pilha, o objeto - no heap
obj.fazerAlgo(variavelLocal); // variavelLocal é passada por valor na nova pilha do quadro
}
private class MyObject {
public void fazerAlgo(int valor) { // valor - na pilha do quadro fazerAlgo
// Método aninhado, adiciona um novo quadro à pilha
outraMetodo();
}
}
private void outraMetodo() {
// Este método cria um novo quadro na pilha
}
}