Java dans Docker et Kubernetes : éviter OOMKilled

Le pod redémarre. kubectl get pod affiche OOMKilled, le code de sortie est 137. Pourtant, les logs ne montrent aucune OutOfMemoryError, et le heap était loin d’être plein. Ce n’est pas la JVM qui a manqué de mémoire : c’est le conteneur. Le noyau Linux a tué le processus parce qu’il a dépassé sa limite. Cet article montre ce que la JVM voit dans un conteneur, ce qui s’ajoute au heap, comment reproduire le kill, et comment régler la mémoire pour que tout tienne. Tous les exemples sont dans le dossier containers/ du dépôt public java-gc-lab. Ils utilisent les images officielles eclipse-temurin : pas d’image à construire. ...

23 octobre 2026 · 10 min

Heap dump Java : trouver une fuite mémoire avec Eclipse MAT

Dans l’article sur les fuites mémoire, deux histogrammes de jcmd montraient quelle classe grossit. Mais pas qui la retient. Pour ça, il faut un heap dump : une photo de tout le heap, avec les objets et les liens entre eux. On reprend la même fuite : UnboundedCache.java, un cache HashMap statique qui reçoit une nouvelle clé à chaque requête. On l’analyse avec Eclipse Memory Analyzer (MAT), un outil open source que le guide d’Oracle cite pour analyser les heap dumps. Toutes les commandes sont dans le dossier heap-dump du dépôt java-gc-lab. ...

23 octobre 2026 · 5 min

Fuites mémoire en Java : 6 cas classiques, reproduits

En Java, le garbage collector libère les objets que plus rien ne référence. Une fuite mémoire, c’est donc un objet devenu inutile mais encore référencé : le GC ne peut pas le libérer. Le guide d’Oracle le dit ainsi : l’application garde des références à des objets « sans le vouloir ». Voici six fuites classiques, chacune reproduite par un petit programme du dépôt public java-gc-lab, avec ce qu’on voit et la correction. ...

23 octobre 2026 · 6 min

OutOfMemoryError en Java : chaque message, reproduit

Une OutOfMemoryError, ce n’est pas un seul problème. Le texte après les deux-points dit quelle zone de la mémoire est pleine : le heap, le Metaspace, la mémoire directe ou les threads. Et chaque zone se vérifie et se corrige autrement. Pour chaque message, j’ai écrit un petit programme qui le provoque. Ils sont dans le dépôt public java-gc-lab, un fichier par message, à lancer avec java sans compiler (Java 11 ou plus). ...

22 octobre 2026 · 8 min

Générations et cycles de GC : Young, Old, Minor, Major, Full

Minor GC, Major GC, Full GC : des mots qu’on lit partout, mais pas toujours avec le sens que leur donne la documentation officielle. La plupart des objets meurent jeunes. La JVM range donc les objets récents dans la Young, et ceux qui durent dans la Old. Un GC qui ne nettoie que la Young est rapide, et il passe souvent. Pourquoi des générations Le guide officiel d’Oracle sur le garbage collector part d’une observation : la plupart des objets ne vivent que très peu de temps. On l’appelle l’hypothèse générationnelle. Un objet créé pour une requête, une boucle ou un calcul devient inutile presque tout de suite. ...

22 octobre 2026 · 6 min

La mémoire de la JVM : Heap, Stack, Metaspace

Votre vieille configuration Java ne démarre plus en Java 17 ? La réponse est dans la mémoire de la JVM. En Java, chaque thread a sa stack, pour ses variables locales. Les objets vivent dans le heap, la zone que le garbage collector nettoie. Les classes sont décrites dans le Metaspace, hors du heap. Et la JVM utilise encore d’autres zones de mémoire, qu’on oublie souvent. Trois zones à connaître La mémoire d'un processus Java : les stacks des threads, le heap, le Metaspace et les autres zones natives Processus Java tout ce qui est hors du heap est de la mémoire native Stacks une par thread · -Xss Thread main traiter() · client main() Thread 2 lire() run() frames, variables locales Heap partagé · géré par le GC · -Xmx Client String List byte[] les objets créés avec new les chaînes internées les champs statiques des classes Metaspace mémoire native sans limite par défaut Client champs, méthodes… String champs, méthodes… la description des classes -XX:MaxMetaspaceSize Et aussi, en mémoire native Code cache le code compilé par le JIT 240 Mo au maximum par défaut Direct memory ByteBuffer.allocateDirect() -XX:MaxDirectMemorySize Structures internes du garbage collector, du compilateur… La stack : une par thread Chaque thread a sa propre stack. À chaque appel de méthode, la JVM y ajoute une frame : les paramètres et les variables locales de la méthode. Quand la méthode se termine, sa frame disparaît. Pas besoin du garbage collector pour libérer cette mémoire. ...

22 octobre 2026 · 5 min