Sobes.tech
Intern

Qu'est-ce qu'un ramasse-miettes (garbage collector) ?

sobes.tech IA

Réponse de l'IA

Sur iOS, ARC (Automatic Reference Counting) est utilisé — un mécanisme de comptage automatique des références qui n’est pas un ramasse-miettes traditionnel. Au lieu de scanner périodiquement la mémoire, ARC gère automatiquement la mémoire en insérant des appels à retain, release et autorelease dans le code lors de la compilation.

Principe de fonctionnement de l’ARC :

  • Chaque objet a un compteur de références.
  • Lors de la création d’un objet ou de l’attribution d’une référence forte, le compteur augmente (retain).
  • Lorsqu’une référence forte est mise à nil ou sort de la portée, le compteur diminue (release).
  • Lorsque le compteur atteint zéro, l’objet est libéré de la mémoire.

Avantages de l’ARC :

  • Libération de mémoire déterministe (on sait quand un objet sera supprimé).
  • Pas de pauses liées au ramasse-miettes traditionnel.
  • Haute performance.

Inconvénients de l’ARC :

  • Les références cycliques (cycles de retention) peuvent entraîner des fuites de mémoire si l’on n’utilise pas de références faibles (weak) ou non possédées (unowned).

Exemple de référence cyclique et sa solution :

class Person {
    let name: String
    var apartments: [Apartment] = [] // Référence forte à Apartment
    init(name: String) { self.name = name }
    deinit { print("\(name) est en train d’être désinitialisé") }
}

class Apartment {
    let unit: String
    weak var tenant: Person? // Référence faible à Person
    init(unit: String) { self.unit = unit }
    deinit { print("Appartement \(unit) est en train d’être désinitialisé") }
}

// Création d’une référence cyclique
var john: Person? = Person(name: "John Appleseed")
var unit4A: Apartment? = Apartment(unit: "4A")

john?.apartments.append(unit4A!)
unit4A?.tenant = john

// L’attribution à nil ne libère pas la mémoire à cause du cycle
john = nil
unit4A = nil
// Les messages de deinit ne s’afficheront pas

// Solution avec référence faible
class FixedPerson {
    let name: String
    var apartments: [FixedApartment] = []
    init(name: String) { self.name = name }
    deinit { print("\(name) est en train d’être désinitialisé") }
}

class FixedApartment {
    let unit: String
    weak var tenant: FixedPerson? // Référence faible à Person
    init(unit: String) { self.unit = unit }
    deinit { print("Appartement \(unit) est en train d’être désinitialisé") }
}

var fixedJohn: FixedPerson? = FixedPerson(name: "John Appleseed")
var fixedUnit4A: FixedApartment? = FixedApartment(unit: "4A")

fixedJohn?.apartments.append(fixedUnit4A!)
fixedUnit4A?.tenant = fixedJohn

// L’attribution à nil libère maintenant la mémoire
fixedJohn = nil
fixedUnit4A = nil
// Les messages de deinit apparaîtront

Contrairement aux ramasse-miettes traditionnels (par exemple, en Java ou Python), qui suspendent l’exécution du programme pour rechercher et libérer les objets inutilisés, l’ARC fonctionne de manière plus efficace et prévisible dans le contexte du développement mobile.