Sobes.tech
Middle+

Como é que a memória é estruturada no iOS?

sobes.tech IA

Resposta da IA

O iOS utiliza uma estrutura hierárquica de memória com vários tipos:

  1. RAM (Memória de Acesso Aleatório):

    • Tipo de memória rápida e dependente de energia.
    • Usada para armazenar aplicações ativas e dados.
    • Gerida pelo sistema operativo e pelo mecanismo ARC (Contador de Referência Automático) para objetos Swift/Objective-C.
    • Quando a memória é escassa, o sistema pode encerrar (terminar) aplicações menos ativas.
  2. Memória incorporada (NAND Flash):

    • Mais lenta que a RAM, mas não volátil.
    • Usada para armazenar o sistema operativo, aplicações, dados do utilizador (fotos, vídeos, documentos).
    • Tem um recurso limitado em número de ciclos de reescrita.
  3. Memória cache (L1, L2, L3):

    • Memória muito rápida ao nível do processador.
    • Usada para armazenar instruções e dados de uso frequente para acelerar o acesso à RAM.

ARC (Contador de Referências Automático)

  • Mecanismo de gestão de memória em Swift e Objective-C que rastreia e gere automaticamente as referências aos objetos.
  • Cada objeto tem um contador de referências. Quando chega a zero, a memória ocupada pelo objeto é libertada.
  • Previna fugas de memória, mas requer atenção ao trabalhar com ciclos de referências fortes (strong reference cycles) que podem ser resolvidos com weak ou unowned.

Memória Virtual

  • O iOS usa memória virtual, permitindo que os programas utilizem um espaço de endereçamento maior que a RAM física disponível.
  • As páginas de memória podem ser transferidas entre a RAM e o sistema de ficheiros (limitado no iOS, principalmente pela limpeza de páginas não utilizadas, e não por troca completa em disco como no macOS).
  • Mecanismos como a "memória comprimida" podem comprimir páginas em vez de as escrever no armazenamento.

Gestão de Memória na Aplicação

  • O programador trabalha principalmente com memória através do ARC.
  • É importante evitar fugas de memória usando corretamente weak e unowned.
  • Deve otimizar o consumo de memória, por exemplo, carregando recursos sob demanda, usando estruturas de dados eficientes e evitando criar objetos em excesso.
  • Ferramentas como Xcode Instruments (Allocations, Leaks) são usadas para perfil de consumo de memória e deteção de fugas.

Exemplo de uso de weak para prevenir ciclos de referências fortes:

class Person {
    let name: String
    var apartment: Apartment?

    init(name: String) {
        self.name = name
        print("Person \(name) is being initialized")
    }

    deinit {
        print("Person \(name) is being deinitialized")
    }
}

class Apartment {
    let unit: String
    weak var tenant: Person? // Usar 'weak' aqui

    init(unit: String) {
        self.unit = unit
        print("Apartment \(unit) is being initialized")
    }

    deinit {
        print("Apartment \(unit) is being deinitialized")
    }
}

var john: Person? = Person(name: "John Appleseed")
var unit4A: Apartment? = Apartment(unit: "4A")

john?.apartment = unit4A
unit4A?.tenant = john

// Se o tenant fosse forte, ao colocar john e unit4A a nil,
// os objetos Person e Apartment não seriam desinitializados
john = nil // deinit chamado para john
unit4A = nil // deinit chamado para unit4A