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

JFR, jcmd, VisualVM : quel outil pour la mémoire Java

Dans cette série, on a déjà utilisé une demi-douzaine d’outils : les logs du GC, jstat, plusieurs commandes jcmd, Eclipse MAT. Chacun répond à une question précise, et chacun a un coût. Cet article les range, puis montre JFR, l’outil le plus complet du JDK, sur un exemple : trouver la méthode qui crée des millions d’objets. Quel outil pour quelle question Question Outil Commande Coût Le GC fait-il des pauses longues ? Le heap après GC monte-t-il ? Logs du GC -Xlog:gc*:file=gc.log à garder en production Quelle zone se remplit, en direct ? jstat jstat -gcutil <pid> 1s non indiqué ; « expérimental et non supporté » d’après sa doc Combien de heap est utilisé ? jcmd jcmd <pid> GC.heap_info moyen Quelle classe grossit ? jcmd jcmd <pid> GC.class_histogram élevé : lance un Full GC Qui retient les objets ? heap dump + Eclipse MAT jcmd <pid> GC.heap_dump élevé : un gros fichier Le Metaspace grossit-il ? jcmd jcmd <pid> VM.metaspace moyen Que fait la mémoire native ? jcmd + NMT -XX:NativeMemoryTracking=summary, puis jcmd <pid> VM.native_memory moyen Que font les threads ? jcmd jcmd <pid> Thread.print moyen Quelle méthode alloue, où sont les pauses, dans le temps ? JFR -XX:StartFlightRecording, puis jfr view faible avec la configuration default Le coût « moyen » ou « élevé » des commandes jcmd est celui qu’indique leur documentation. Chacun de ces outils a déjà servi dans un article : les logs du GC, les OutOfMemoryError, les fuites mémoire et le heap dump avec Eclipse MAT. ...

23 octobre 2026 · 5 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

Lire un log GC en Java : chaque chiffre expliqué

Activer le log du GC est facile. Le lire l’est moins : une ligne de G1 contient une dizaine d’informations, et les mots changent d’une version de Java à l’autre. Cet article lit de vraies lignes, produites par trois petits programmes du dépôt public java-gc-lab : une charge normale, des objets très gros, et un heap presque plein. Activer le log java -Xlog:gc*:file=gc.log:time,uptime,level,tags -jar app.jar gc* : tous les messages du GC (gc seul donne une ligne par GC) ; file=gc.log : dans un fichier, avec une rotation déjà intégrée (5 fichiers d’environ 20 Mo par défaut) ; time,uptime,level,tags : les « décorations » au début de chaque ligne : la date et l’heure, le temps depuis le démarrage de la JVM, le niveau et les tags. Sans rien préciser, la JVM met uptime, level et tags. Une ligne de pause, avec ces décorations : ...

22 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

Garbage collector Java : le guide à jour (Java 25)

Sur le garbage collector Java, on trouve beaucoup d’articles, et beaucoup sont anciens : PermGen, CMS, -XX:+PrintGCDetails… Ce guide résume ce qui est vrai en Java 25, en quelques lignes par sujet. Chaque partie renvoie à un article plus complet, où chaque fait est vérifié dans la documentation officielle ou sur une vraie JVM. Je mets ce guide à jour quand la série avance, ou quand une nouvelle version de Java change les règles. ...

22 octobre 2026 · 6 min

Idées reçues sur le garbage collector Java

Sur le garbage collector, on lit encore beaucoup de conseils. Certains étaient faux dès le départ, d’autres ne sont plus vrais aujourd’hui. Voici cinq idées reçues, et ce que disent la documentation officielle et une vraie JVM en Java 25. « System.gc() force un GC » Non : c’est une demande, pas un ordre. La javadoc dit que System.gc() « suggère » à la JVM de libérer de la mémoire, sans aucune garantie sur la quantité libérée, ni même que le travail soit fait. ...

22 octobre 2026 · 4 min

Les options JVM qui comptent, et celles qui ne marchent plus

Vous reprenez un vieux script de démarrage, vous passez à Java 25, et la JVM ne démarre plus : Unrecognized VM option 'PrintGCDateStamps' Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program will exit. Beaucoup d’options mémoire et GC qu’on trouve encore sur le web ont changé ou disparu. Certaines sont juste ignorées, d’autres empêchent la JVM de démarrer. Et les options utiles aujourd’hui tiennent en quelques lignes. ...

22 octobre 2026 · 5 min

Les garbage collectors Java en 2026 : lequel tourne chez vous ?

Votre application tourne peut-être avec un autre GC que celui que vous croyez. En Java 25, G1 est le garbage collector par défaut. Mais la JVM en propose d’autres, chacun pour un besoin. Et sur une petite machine, elle en choisit un autre toute seule. Les GC disponibles en Java 25 GC Ce qu’en dit le guide d’Oracle Option Serial Un seul thread pour tout le travail du GC. Pour un petit jeu de données (jusqu’à 100 Mo environ) ou un seul processeur -XX:+UseSerialGC Parallel Le « throughput collector » : comme Serial, mais avec plusieurs threads. Si la performance brute compte le plus, et que des pauses d’une seconde ou plus sont acceptables -XX:+UseParallelGC G1 Un GC « en grande partie concurrent » : il fait une partie du travail pendant que l’application tourne. Si le temps de réponse compte plus que le débit -XX:+UseG1GC ZGC Des pauses de moins d’une milliseconde, au prix d’un peu de débit. Si la latence est la priorité -XX:+UseZGC Shenandoah Un GC à pauses courtes, lui aussi. Le guide d’Oracle n’en parle pas ; il fonctionne avec Temurin 25 -XX:+UseShenandoahGC Et un cas à part : Epsilon. Il alloue la mémoire, mais ne la libère jamais. Quand le heap est plein, la JVM s’arrête. Il sert pour des tests (mesurer une application sans GC, vérifier qu’un test ne crée pas trop d’objets) ou des tâches très courtes. En Java 25, il est encore expérimental : il faut -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC. ...

22 octobre 2026 · 4 min