1 points par GN⁺ 2024-11-12 | 1 commentaires | Partager sur WhatsApp
  • 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, #29 et #30

1 commentaires

 
GN⁺ 2024-11-12
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 final qui, à 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ème
    La 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

    • Dans le cadre de notre stratégie integrity by default [1], nous sommes en train de changer cela, et un JEP correspondant devrait bientôt arriver
      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 explicitement open; à l’avenir, l’application devra donc accorder une autorisation au module qui veut modifier final
      C’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
    • Je me demande si certains, en suivant aveuglément Effective Java, n’ont pas commis le péché originel consistant à dire mettez final partout
      Résultat, on ne peut plus facilement mocker des classes final dans les tests, et les outils de mock doivent aller jusqu’à faire de la manipulation de bytecode pour mocker des classes final
      Par 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 mocker
    • Le cas de System.out est un problème propre à Java
      https://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
    • Les modificateurs de champs ne sont pas des contraintes de sécurité, mais des contraintes sémantiques
      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
    • J’avoue avoir déjà écrit moi-même, il y a longtemps, un bout de code malveillant en trois lignes dans une bibliothèque interne disparue depuis, pour éviter un refactoring pénible : rendre un membre “un-final”, le modifier, puis le rendre à nouveau comme final
      J’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

    • Si l’on peut appeler cela “moderne”, les approches multiplateformes actuelles sont intéressantes
      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’ ?

    • Il me semble que le nom a été changé quand les révélations sur le comportement en ligne de Justin Rolland ont commencé à émerger
  • 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

    • Je ne pense pas être le seul, mais c’est probablement que je me trouve dans des situations où Java n’est pas nécessaire
      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
    • Pour compléter les autres réponses, Java possède aussi largement les caractéristiques nécessaires à une startup, donc l’utiliser pour un nouveau projet se défend
      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
    • Sur la JVM, il existe beaucoup de langages très agréables à utiliser, comme Clojure
      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.
    • Pour répondre de manière inflammable à un commentaire inflammable : Java est meilleur que Go sur tous les plans, et 90 % de presque tous les cas que vous avez cités peuvent être traités avec Java
      Donc, pour à peu près tout, Java est un choix assez clairement bon
    • Vous n’êtes sans doute pas le seul, mais tout le monde ne partage pas cet avis non plus
      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