ProgrammationDéveloppeur Java

Comment fonctionne le mécanisme de gestion automatique de la mémoire en Java (Garbage Collector) ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

En Java, la gestion de la mémoire est effectuée par le biais de la collecte automatique des déchets (Garbage Collector, GC). La JVM suit les objets en mémoire : si un objet n’a plus de références, il devient inaccessible et peut être supprimé.

Le GC se compose de différentes phases, telles que Mark, Sweep et parfois Compact. Dans la phase Mark, les objets accessibles depuis les racines (GC roots) sont marqués comme vivants. Après cela, commence la phase Sweep : les objets non utilisés sont supprimés. Parfois, Compact est exécuté — la défragmentation de la mémoire.

Il existe différents types de GC : Serial, Parallel, CMS, G1. Ils doivent être choisis en fonction du type de charge sur l'application.

Exemple de code — situation de fuite de mémoire :
List<byte[]> dataList = new ArrayList<>(); while(true) { dataList.add(new byte[1024*1024]); // Les objets restent accessibles }

Dans cet exemple, les objets ne deviendront jamais inaccessibles, le GC ne les supprimera pas, et cela entraînera un OutOfMemoryError.

Question piège

Si un objet n’a plus de références, quand est-il garanti que son finaliseur (finalize()) sera appelé ?

Réponse : L'appel de la méthode finalize() n'est pas du tout garanti ! Il peut ne pas être appelé ou être appelé avec un retard. On ne peut pas compter sur finalize() pour libérer des ressources.

@Override protected void finalize() throws Throwable { // Peut ne pas fonctionner ! }

Exemples d'erreurs réelles dues à une méconnaissance des subtilités du sujet


Histoire

Dans un grand système de e-commerce, les développeurs espéraient automatiser le nettoyage des fichiers temporaires en utilisant la méthode finalize(), mais en raison de l'appel rare de cette méthode, le cache a débordé de fichiers temporaires, entraînant un manque d'espace disque et des temps d'arrêt.


Histoire

Dans un API REST à forte charge, un cache interne de références à de grands objets a été sauvegardé par inadvertance, ce qui a empêché la libération de mémoire. Après un crash de l'application avec OutOfMemoryError, une analyse a révélé une erreur dans la méthode de mise en cache.


Histoire

Des finaliseurs ont été utilisés pour libérer des connexions réseau, considérées comme "un moyen sûr". Cela a conduit à des connexions qui restaient dans le système pendant une durée indéfinie, provoquant des blocages et l'épuisement du pool de connexions.