- Une série de mini-billets en cours qui découpe les connaissances internes de la JVM en petites unités ; chaque article se concentre sur un sujet, un test, un benchmark ou une observation
- Chaque billet vise une lecture en 5 à 10 minutes et part du principe que les éléments de la JVM interagissent entre eux
- Les preuves et discussions peuvent être anecdotiques, et la vérification des erreurs, de la cohérence, du style, de la grammaire et des doublons peut être insuffisante ; il faut donc rester prudent avant de s’y fier tel quel
- L’ensemble complet est fourni aux formats ePUB, MOBI, PDF ; le PDF pèse plusieurs dizaines de Mo en raison d’une conversion de haute qualité
- L’index des articles individuels est réparti selon les axes Compiler, Runtime, GC et Library, et couvre des sujets internes à la JVM comme l’optimisation des verrous, les TLAB, les pauses GC,
String.intern(), les safepoints, les références compressées et les déplacements conditionnels
Prérequis pour lire la série
- JVM Anatomy Quarks est une série de mini-billets en cours qui synthétise les connaissances de base sur la JVM sous forme d’articles courts
- Chaque billet approfondit un sujet, un test, un benchmark ou une observation
- Pris isolément, un billet peut manquer de contexte, et la plupart des éléments abordés peuvent facilement interagir entre eux
- Les preuves et discussions des articles peuvent être anecdotiques, et la vérification des erreurs, de la cohérence, du style, de la grammaire, du sens et des doublons peut être insuffisante
- Toute utilisation ou confiance accordée au contenu se fait aux risques du lecteur
Fichiers groupés et structure de l’index
- L’ensemble complet de la série est fourni dans trois formats
- ePUB est le plus petit, sous le Mo, et repose sur une conversion HTML vers ePUB avec Pandoc
- MOBI est léger, de l’ordre du Mo, et repose sur une conversion ePUB vers MOBI avec KindleGen
- PDF est très volumineux, de l’ordre de plusieurs dizaines de Mo, et correspond à une sortie haute qualité basée sur une conversion HTML vers PDF avec wkhtmltopdf
- L’index individuel est organisé en catégories Compiler, Runtime, GC, Library
Liste des articles par sujet
-
Articles axés sur Compiler
#1: Lock Coarsening and Loops#14: Constant Variables#15: Just-In-Time Constants#16: Megamorphic Virtual Calls#17: Trust Non-Static Final Fields#18: Scalar Replacement#19: Lock Elision#20: FPU Spills#25: Implicit Null Checks#27: Compiler Blackholes#28: Frequency-Based Code Layout#29: Uncommon Traps#30: Conditional Moves
-
Articles mêlant Runtime et GC
- Des articles qui traitent du comportement de la mémoire et des pauses pendant l’exécution de la JVM
#2: Transparent Huge Pages#4: TLAB Allocation#5: TLABs and Heap Parsability#6: New Object Stages#7: Object Initialization Costs#9: JNI Critical and GC Locker#22: Safepoint Polls
-
Articles axés sur GC
- Ils abordent principalement la conception des collecteurs et le comportement du tas
#3: GC Design and Pauses#11: Moving GC and Locality#13: Intergenerational Barriers#21: Heap Uncommit
-
Articles axés sur Runtime
- Des articles qui traitent de l’environnement d’exécution de la JVM et de la représentation des objets
#12: Native Memory Tracking#23: Compressed References#24: Object Alignment#26: Identity Hash Code
-
Articles Library ou à classification multiple
- Parmi les articles incluant Library figure
#10: String.intern() - Les articles également marqués Compiler et Runtime sont
#16,#25,#29et#30
- Parmi les articles incluant Library figure
1 commentaires
Avis de Hacker News
https://shipilev.net/jvm/anatomy-quarks/17-trust-nonstatic-f... est vraiment un cas regrettable
Comme certains frameworks ont abusé de JNI et de la réflexion pour modifier des champs
finalqui, à l’origine, auraient dû être immuables, le code utilisateur passe à côté d’optimisations importantes qui ne sont possibles que pour les classes fournies par le systèmeLa plateforme, en particulier le compilateur et le runtime, doit faire respecter très strictement les contraintes sémantiques afin de préserver les possibilités d’optimisation futures
En réalité, peu de code a réellement besoin de modifier
final, et même aujourd’hui cette opération est limitée aux classes de son propre module ou aux classes explicitementopen; à l’avenir, l’application devra donc accorder une autorisation au module qui veut modifierfinalC’est similaire à l’approche que nous avons récemment appliquée aux appels natifs et aux accès mémoire non sûrs
[1]: https://openjdk.org/jeps/8305968
finalpartoutRésultat, on ne peut plus facilement mocker des classes
finaldans les tests, et les outils de mock doivent aller jusqu’à faire de la manipulation de bytecode pour mocker des classesfinalPar exemple, chez Google, Effective Java est une exigence interne, donc même l’API publique GDrive contient des classes
final, alors qu’une API externe est précisément le genre de chose qu’on veut mockerSystem.outest un problème propre à Javahttps://docs.oracle.com/javase/specs/jls/se7/html/jls-17.htm...
Avec un tel précédent, il n’est pas surprenant que d’autres aient pensé que c’était une pratique acceptable
Il est normal qu’on puisse les contourner en passant par une procédure de contournement appropriée
L’enjeu central est la sûreté, car modifier quelque chose qui ne devrait pas l’être peut provoquer un SEGV, et c’est justement ce type de préoccupation que les modificateurs d’accès cherchent à traiter
finalJ’aurais préféré que ce soit impossible, mais il y avait un besoin métier
C’est un peu un autre sujet, mais Apple vient de sortir un nouveau pont Swift Java, et il est plutôt chouette
Il prend en charge à la fois JNI et Panama, et la semaine dernière j’étais en train de le porter sur Android
https://github.com/swiftlang/swift-java
L’interopérabilité entre langages permet, quand c’est pertinent, de partager une même bibliothèque sur plusieurs plateformes
Jusqu’ici, on faisait cela uniquement avec C++, en ajoutant une API C si nécessaire, mais quand C++ n’est pas requis en soi, ce n’est évidemment pas le langage qu’on préfère
Cela dit, le coût m’inquiète. Si Swift peut facilement appeler une bibliothèque Kotlin dans une app mobile, j’imagine qu’une app iOS devra charger, sous une forme ou une autre, quelque chose qui ressemble à une JVM; et inversement, si une app Android appelle Swift, elle devra probablement charger le runtime Swift
Au final, cela crée de l’overhead
Je crains qu’un jour il devienne courant que des développeurs dépendent de bibliothèques Swift, qui dépendent elles-mêmes de bibliothèques Kotlin lançant une JVM, laquelle appelle ensuite du C++ via JNI
Cela ressemble à la situation des gestionnaires de paquets modernes : on n’a que quelques dépendances directes, mais parce que c’est “trop facile pour qu’on y fasse attention”, le programme se retrouve très vite avec plus de 100 dépendances transitives
Je suis content que cette excellente série d’articles ait été partagée ici. J’ai beaucoup appris sur la JVM en la lisant
J’aime particulièrement cet article qui explique pourquoi l’expression qu’on appelle couramment “allocation sur la pile” en Java est incorrecte : https://shipilev.net/jvm/anatomy-quarks/18-scalar-replacemen...
Ce que fait réellement la JVM, c’est de l’analyse d’échappement + remplacement scalaire
J’aime le format de ces articles
On peut en lire un d’une traite en quelques minutes et, si l’on veut, lancer les benchmarks localement
Si vous avez travaillé quelques années avec des langages basés sur la JVM, cette collection d’articles est vraiment passionnante
Je me souviens encore de ma première lecture, il y a quelques années
Quelqu’un sait pourquoi cette série a changé de nom, alors qu’elle s’appelait auparavant ‘JVM Anatomy Park’ ?
J’en suis venu à presque oublier Java
L’idée de démarrer un nouveau projet en Java ne me vient absolument pas à l’esprit
Si j’ai besoin de développement rapide et de flexibilité, je choisirais Python ; si je veux gérer beaucoup de concurrence d’E/S avec un garbage collector, Go ; si j’ai besoin d’un bon langage compilé et équilibré, Swift ; et si je veux un langage compilé avec de la performance et de la sûreté, Rust
Ce n’est qu’une préférence personnelle, et je sais que Kotlin rend Java plus agréable à utiliser, mais c’est quand même l’impression que j’ai
Les grands atouts de Java sont qu’il existe une quantité presque infinie de développeurs ayant de l’expérience en Java, un vaste ensemble de bibliothèques existantes dont beaucoup sont orientées entreprise, qu’il est facile de gérer de très grandes bases de code avec de nombreux contributeurs, et que sa VM standard, développée depuis des décennies, est extrêmement robuste, assez rapide, et prise en charge sur pratiquement toutes les plateformes
Java n’a plus la domination écrasante qu’il avait au début des années 2000, même en entreprise, et c’est un langage « blub » typique ; mais si l’on prévoit une échelle entreprise et qu’il est plus important de faire monter en charge une grande équipe de développeurs que d’optimiser la performance pure, cela reste un choix tout à fait raisonnable
J’aime Rust, mais c’est Java qui me fait vivre
Grâce aux frameworks modernes et à l’assistance par IA, on peut mettre en place un backend correct en quelques jours
Si vous êtes cofondateur technique solo, il suffit de connaître Java ou Kotlin, ainsi qu’une stack frontend, pour construire rapidement un MVP ; en pratique, vous passerez beaucoup plus de temps sur des tâches hors code, donc les différences de fonctionnalités entre langages compteront moins
Si vous partez sur du mobile natif, Swift peut devenir votre deuxième langage
De plus, il est probable que la scalabilité ne soit pas le premier problème pendant un bon moment. La montée en taille de l’équipe arrivera d’abord, et les goulets d’étranglement de performance ne deviendront visibles que bien plus tard
Java convient bien aux grandes équipes
D’un point de vue business, si vous voulez un vivier de talents plus large, des cycles de livraison rapides et une stack susceptible de rester centrale sur le long terme, Java ou Kotlin sont probablement les meilleurs choix
Vous pouvez choisir Go ou Rust si vous voulez mettre en avant une techno séduisante comme avantage pour attirer un certain profil de développeurs, ou si vous avez un cas métier rare
Python est populaire dans le monde académique et les bootcamps, mais, franchement, je ne vois pas très bien sa valeur business pour un backend généraliste
Je ne mettrais pas toute la JVM de côté. La JVM est un chef-d’œuvre d’ingénierie et elle évolue rapidement aujourd’hui. Il suffit de regarder Loom, Panama, Leyden, etc.
Donc, pour à peu près tout, Java est un choix assez clairement bon
Kotlin avec Java 21+ est mon choix par défaut pour les services centrés sur les E/S, et en fait pour quasiment n’importe quel service
C’est vraiment agréable à utiliser, et grâce aux threads virtuels, on peut écrire du code aussi simple et efficace qu’en Go, tout en profitant de l’un des écosystèmes de bibliothèques les plus vastes et les meilleurs au monde
Je ne cherche pas à dénigrer Go ou Python. Si ce sont vos outils préférés, ils sont tout à fait valables
Mais Java n’est pas devenu aussi hors sujet que vous le pensez