Cyril Mottier

“It’s the little details that are vital. Little things make big things happen.” – John Wooden

Devenez Le Maitre Des Références Sous Android

Note : L'article suivant ne traite pas particulièrement de technologies et d'APIs propres à Android. La plupart des APIs mentionnées ci-dessous sont en fait des APIs propres à Java lui-même. Néanmoins, elles sont énormément utiles dans le contexte d'Android … pourquoi ? Eh bien je ne vais pas le dire ici car c'est l'objet de cet article ! Bonne lecture

La programmation sur terminaux mobile est contrainte par un nombre importants de facteurs. L'objectif n'est pas ici de faire une liste exhaustive de tous ces facteurs car je pense l'avoir fait dans de nombreux précédents posts. Nous allons simplement traiter ici d'une des contrainte majeure : la gestion de la mémoire.

La gestion de la mémoire étant omniprésente dans tous systèmes informatique, les plateformes offrent des systèmes de gestion tous plus différents les uns que les autres. Certains environnement sont “garbage collectés” (c'est le cas d'Android) alors que d'autres offrent une gestion de la mémoire manuelle (c'est le cas de l'iPhone par exemple : lorsque vous créer un objet - message alloc - vous devez explicitement mentionner que vous ne l'utilisez plus - message release - pour que le système le supprime). Je ne vais pas rentrer dans un débat sans fin pour dire quel modèle est vraiment le plus avantageux car je pense qu'aucun n'est parfait … tout dépend du contexte dans lequel on les utilise.

En Java, lorsque vous créer un objet, vous créer en réalité une référence vers cet objet. La durée de vie d'un objet Java décrit souvent le schéma suivant :

  • L'objet O est créé et le développeur dispose d'une référence A sur ce dernier

  • L'objet O commence à “vivre” : il est référencé par d'autres objets B, C et D

  • Les objets B, C et D n'utilise plus 0 est donc le compte de référence sur O repasse à 1 (référence A)

  • La référence A n'est plus utilisée et l'objet O devient donc “non référencé” : c'est à ce moment là que le garbage collector considère qu'il est possible de supprimer l'objet de la mémoire.

Laisser le garbage collector gérer lui-même la mémoire facilite grandement le développeur. Malheureusement il arrive parfois que ce dernier prenne ses aises et qu'il utilise trop de mémoire. Le résultat est souvent impitoyable et se résume en une unique Exception que nous devrions tous essayer d'éviter : OutOfMemoryException. Comme son nom l'indique, cette Exception indique qu'il n'y a plus assez de mémoire pour créer l'objet.

Avant d'introduire la solution à ce problème j'aimerai donner la philosophie qui a été choisie sur l'iPhone SDK pour permettre de résoudre ce problème. Le SDK fournit un réalité un centre de notifications : le NSNotificationCenter. Il est possible de s'enregistrer auprès de ce centre de notification et ainsi être notifié de possibles messages du système. Dans notre cas, il suffit d'écouter le message UIApplicationDidReceiveMemoryWarningNotification (oui je sais il est long ce nom … vive l'autocomplétion !) afin de savoir quand il devient urgent de supprimer des objets inutiles/recréables de la mémoire (caches, objets inutilisé, etc.)

Java n'inclut pas ce genre de système. Néanmoins il est possible de gérer la mémoire de façon plus précise en utilisant un des 3 types de référence présentés ci-dessous :

  • Reference : C'est la référence classique. C'est le type de référence par défaut utilisée partout dans Java. La durée de vie d'un objet rattaché par une Reference a été expliqué précédemment

  • WeakReference : C'est une référence qui indique au GC que l'objet référencé peut être supprimé si et seulement si il est référencé uniquement par une ou plusieurs WeakReferences.

  • SoftReference : Un objet référencé par une ou plusieurs SoftReference sera supprimé de la mémoire lorsque le GC va considérer que le système manque de mémoire. C'est donc la référence parfaite pour émuler le comportement décrit ci-dessus. C'est pourquoi on utilise souvent cette référence lors de l'élaboration de caches par exemple.

Il existe encore un autre type de référence nommé PhantomReference mais je ne pense pas qu'elle est une utilité dans vos développements Android. Vous voilà maintenant fin prêt pour parfaire la gestion mémoire de votre application !