Sobes.tech
Middle

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
    }
}