Sujet : jvm
-
Quels signaux d'observabilité un service JVM ou .NET devrait-il émettre par défaut, et à quel coût ?
Question ouverte : les deux environnements d'exécution embarquent une télémétrie native (Flight Recorder et la journalisation du GC sur la JVM ; les compteurs EventPipe et dotnet-trace sur .NET) et disposent tous deux d'une auto-instrumentation OpenTelemetry, mais il existe peu de preuves partagées sur lesquels de ces signaux devraient être activés en permanence en production, ce qu'ils coûtent, et lesquels ont réellement raccourci des incidents.
-
Écrire un test unitaire en JUnit 5 et xUnit.net : annotations, cycle de vie et cas paramétrés côte à côte
JUnit Jupiter marque les tests avec @Test, exécute @BeforeEach et @AfterEach autour de chacun sur une instance fraîche par défaut, et pilote les cas pilotés par les données avec @ParameterizedTest plus une annotation de source ; xUnit.net utilise [Fact], le constructeur et IDisposable pour l'initialisation par test sur une instance fraîche, [Theory] avec [InlineData] pour les cas, et des fixtures pour un contexte coûteux partagé. Écrire des tests de même forme dans les deux garde alignées les conventions d'une équipe polyglotte.
-
Dimensionner une JVM dans un conteneur : pourcentage de tas, mémoire hors tas et nombre de CPU
La JVM lit par défaut les limites cgroup (UseContainerSupport) et dimensionne le tas comme un pourcentage de la mémoire du conteneur, pas de celle de l'hôte ; le tas n'est qu'une partie de l'empreinte, il faut donc régler MaxRAMPercentage pour laisser de la place au metaspace, aux piles de threads, aux buffers directs et au cache de code, vérifier le nombre de CPU que voit la JVM, et vérifier avec -Xlog:os+container et le suivi de mémoire natif avant de faire confiance à une limite.
-
Maven contre Gradle : ce qu'un nouvel arrivant doit savoir pour construire le projet JVM de quelqu'un d'autre
Maven décrit un projet de façon déclarative dans pom.xml et exécute des phases de cycle de vie fixes (validate, compile, test, package, verify, install, deploy) avec des objectifs de plugin qui s'y rattachent ; Gradle exécute un graphe de tâches configuré par des scripts build.gradle(.kts) et des plugins. Les deux résolvent les dépendances transitives mais avec des règles de conflit différentes (Maven : la définition la plus proche ; Gradle : la version la plus élevée), et les deux fournissent un script wrapper qui fixe la version de l'outil de build.
-
Records Java, types scellés et filtrage par motif pour switch
Les records (JDK 16) sont des porteurs de données transparents et immuables, dotés d'un constructeur canonique généré, d'accesseurs, ainsi que de equals, hashCode et toString ; les types scellés (JDK 17) restreignent les classes autorisées à en hériter ou à les implémenter, de sorte qu'un switch par motif (JDK 21) sur la hiérarchie puisse être vérifié pour son exhaustivité. Ensemble, ils dotent Java d'un type somme léger.
-
Ramasse-miettes de la JVM : les collecteurs, les valeurs par défaut et les rares indicateurs à régler
HotSpot embarque Serial, Parallel, G1 et ZGC ; il choisit G1 sur les machines qu'il considère comme de classe serveur (deux processeurs ou plus et au moins 1792 Mo) et Serial dans les autres cas, avec un tas maximal par défaut d'un quart de la mémoire. Pour la plupart des services, les indicateurs qui valent la peine d'être réglés sont le tas maximal, la journalisation du GC, et, seulement après lecture des journaux, un collecteur ou un objectif de temps de pause.
-
Après le passage d'un service JVM aux threads virtuels, qu'est-ce qui a changé en matière de débit, de mémoire et d'incidents de pinning, et qu'a-t-il fallu réécrire ?
Question ouverte : la JEP 444 indique que le pinning ne rend pas une application incorrecte mais peut nuire à sa scalabilité, et la JEP 491, livrée dans JDK 24, supprime le pinning pour les blocs synchronized ; pour les services ayant fait basculer le traitement des requêtes vers les threads virtuels, quel a été l'effet du changement sur le débit et la mémoire, quels incidents de pinning ou d'épuisement de pool sont survenus, et quel code et quelles bibliothèques ont dû être modifiés ?
-
Les threads virtuels de Java en résumé : ce qui change et ce qui ne change pas
La JEP 444 (JDK 21) ajoute les threads virtuels : des threads bon marché ordonnancés par le JDK sur un petit pool de threads de plateforme porteurs (carriers), qui se démontent lorsqu'ils bloquent sur la plupart des E/S du JDK, de sorte que le code à un thread par requête passe à l'échelle sans style asynchrone. Ils ne sont pas plus rapides, ne doivent jamais être mis en pool, et jusqu'à la JEP 491 (JDK 24), bloquer à l'intérieur d'un synchronized épinglait (pinned) le thread porteur.
-
Flux Java contre boucles : quand un pipeline est plus clair, et quand il ne l'est pas
Un flux (stream) est un pipeline paresseux d'opérations intermédiaires clos par une opération terminale ; il se lit bien pour filtrer, transformer et collecter sur une collection, mais la documentation du paquetage déconseille les effets de bord dans les lambdas, un flux ne peut pas être réutilisé, les exceptions vérifiées ne s'y intègrent pas, et une boucle est plus claire pour une sortie anticipée avec état, un travail indexé et de la mutation.
Lisible par machine : JSON