Rapport du Java Virtual Machine Language Summit 2019


Aujourd'hui s'est terminé le douzième sommet JVM LS . Comme d'habitude, ce fut un événement hardcore avec des présentations techniques sur les machines virtuelles et les langages qui y tournent. Comme d'habitude, le sommet s'est tenu à Santa Clara, sur le campus Oracle. Comme d'habitude, il y a beaucoup plus de personnes qui souhaitent venir ici qu'il n'y a de places: le nombre de participants ne dépasse pas 120. Comme d'habitude, il n'y a pas eu de marketing, seulement des abats.


Ce sommet est déjà le troisième pour moi, et chaque fois que je le visite avec grand plaisir, malgré le terrible décalage horaire. Ici, vous pouvez non seulement écouter des rapports, mais aussi apprendre à mieux connaître les gens du monde de la JVM, participer à des conversations informelles, poser des questions lors d'ateliers et vous sentir généralement impliqué dans de grandes réalisations.


Si vous n'avez pas assisté au sommet, cela n'a pas d'importance. La plupart des rapports sont publiés sur YouTube presque immédiatement après le sommet. En fait, ils sont déjà disponibles . Pour faciliter la navigation, je décrirai brièvement ici tous les reportages et ateliers auxquels j'ai réussi à participer.


29 juillet


Ghadi Shayban - Clojure Futures


Il ne s'agit pas des fonctionnalités de la compilation Future dans le langage Clojure , comme beaucoup le pensaient, mais simplement du développement du langage, des subtilités de la génération de code et des problèmes qu'ils rencontrent. Par exemple, il s'est avéré que dans Clojure, il est important d'annuler les variables locales après la dernière utilisation, car si le début d'une liste qui est généré paresseusement dans une variable locale, puis en la contournant, les nœuds qui ont déjà été contournés peuvent ne pas être collectés par le garbage collector et le programme peut se bloquer avec OutOfMemory . En général, le compilateur C2 JIT libère lui-même les variables après la dernière utilisation, mais la norme ne le garantit pas et, par exemple, l'interpréteur HotSpot ne le fait pas.


Il était également intéressant d'en savoir plus sur la mise en œuvre de la répartition dynamique des appels de fonction. J'ai également appris que jusqu'à récemment, Clojure ciblait JVM 6 et n'était récemment passé à JVM 8. Maintenant, les auteurs du compilateur regardent invokedynamic.


Alan Bateman et Rickard Bäckman - Mise à jour du projet Loom


Le projet Loom est une fibre légère pour Java. Il y a un an, Alan et Ron avaient déjà parlé de ce projet, puis il semblait que tout allait très bien et était sur le point d'être prêt. Cependant, ce projet n'est pas encore officiellement entré dans Java et est toujours en cours de développement dans une fourchette distincte du référentiel. Bien sûr, il s'est avéré qu'il était nécessaire de régler beaucoup de détails.


De nombreuses API standard de ReentrantLock.lock à Socket.accept sont déjà adaptées aux fibres: si un tel appel est effectué à l'intérieur d'une fibre, l'état d'exécution sera enregistré, la pile sera déroulée et le thread du système d'exploitation sera libéré pour d'autres tâches jusqu'à ce qu'un événement réveille la fibre (par exemple, ReentrantLock.unlock). Cependant, par exemple, le bon vieux bloc synchronisé ne fonctionne toujours pas et, semble-t-il, il ne peut pas se passer d'une refactorisation sérieuse de toute la prise en charge de la synchronisation dans la JVM. Un autre déroulement de la pile ne fonctionnera pas s'il y a des trames natives dans la pile entre le début de la fibre et le point d'arrêt. Dans ces deux cas, rien n'explose, mais la fibre ne libère pas le flux.


Il existe de nombreuses questions sur la façon dont Fibre se compare à l'ancienne classe java.lang.Thread. Il y a un an, l'idée était de faire de la fibre une sous-classe de Thread. Maintenant, ils l'ont refusé et en font une entité indépendante, car émuler dans chaque fibre tout le comportement d'un flux régulier est assez cher. Dans ce cas, Thread.currentThread () à l'intérieur de la fibre retournera le blende généré, et non le vrai thread dans lequel tout est exécuté. Mais l'accroche se comportera plutôt bien (même si cela peut ralentir le travail). L'idée importante est de ne donner en aucun cas le véritable flux multimédia sur lequel la fibre s'exécute à l'intérieur de la fibre. Cela peut être dangereux car une fibre peut facilement se déplacer vers un autre fil. La tromperie continuera.


Il est curieux que les participants au projet aient déjà introduit quelques modifications préparatoires dans le référentiel JDK principal afin de leur faciliter la vie. Par exemple, en Java 13, la méthode doPrivileged a été réécrite à partir du code natif entièrement en Java, gagnant environ 50 fois plus de performances. Pourquoi est-ce un projet Loom? Le fait est que cette méthode apparaît très souvent au milieu de la pile, et bien qu'elle soit native, les fibres avec cette pile ne se sont pas arrêtées. D'une manière ou d'une autre, le projet en bénéficie déjà.


Sur la page du projet, vous pouvez lire la documentation et télécharger l'arborescence source, et il existe également des assemblages binaires que vous pouvez prendre et jouer aujourd'hui. Nous espérons que dans les années à venir, tout sera intégré.


Brian Goetz - Atelier "Projet Ambre"


En parallèle, un atelier se déroulait sur le projet Loom, mais je suis allé à Amber. Ici, nous avons brièvement discuté des objectifs du projet et des principaux PEC dans lesquels le travail se poursuit - Correspondance de modèles , types d' enregistrements et de scellés . Ensuite, toute la discussion est tombée dans la question privée de la portée. J'en ai parlé lors de la conférence du Joker l'année dernière, en principe, rien de très nouveau n'a été dit. J'ai essayé de pousser une idée avec des types d'unions implicites comme if(obj instanceof Integer x || obj instanceof Long x) use(x.longValue()) , mais je n'ai pas vu d'enthousiasme.


Jean Christophe Beyler, Arthur Eubanks et Man Cao - Thread Sanitizing for Java


À tous égards, un merveilleux projet de Google pour rechercher des races en utilisant des données sous forme de lecture et d'écriture du même champ non volatile ou élément de tableau à partir de différents flux sans établir de relation antérieure. Le projet a été initialement écrit en tant que module LLVM pour le code natif, et maintenant il a été adapté pour HotSpot. Il s'agit d'un projet OpenJDK officiel avec sa liste de diffusion et son référentiel.


Selon les auteurs, la chose fonctionne maintenant très bien, vous pouvez assembler et jouer. De plus, elle trouve la course non seulement dans le code Java, mais aussi dans le code des bibliothèques natives. Les courses dans le code de la machine virtuelle elle-même ne sont pas recherchées, car toutes les primitives de synchronisation sont écrites à leur manière et TSan n'est pas en mesure de les détecter. Selon les auteurs, TSan ne donne pas de faux positifs.


Le principal problème est la performance. Désormais, seul l'interpréteur est instrumenté pour le code Java, respectivement, la compilation JIT est complètement désactivée et l'interpréteur, qui est déjà lent, ralentit plusieurs fois. Mais si vous avez suffisamment de ressources (Google en a bien sûr assez), vous pouvez occasionnellement piloter vos suites de tests en utilisant TSan. Il est également prévu d'ajouter une instrumentation au JIT, mais il s'agit d'une intervention beaucoup plus sérieuse dans la JVM.


Quelqu'un a demandé si la désactivation de la compilation JIT n'affecte pas le résultat, car certaines races peuvent ne pas apparaître sur l'interpréteur. L'orateur n'a pas exclu cette possibilité, mais a déclaré qu'il avait déjà trouvé un grand nombre de courses qui prendraient très longtemps à ratisser. Soyez donc prudent lorsque vous exécutez votre projet sous TSan: vous pouvez découvrir la vérité désagréable.


Brian Goetz - Mise à jour Valhalla


Tout le monde attend des types de valeurs en Java, mais personne ne sait quand ils apparaîtront. Cependant, les mouvements sont de plus en plus graves. Il existe déjà des assemblages binaires de test avec le jalon L2 actuel. Dans les plans actuels, le Valhalla complet viendra sur le jalon L100, mais les auteurs sont toujours optimistes et croient que plus de deux pour cent ont été réalisés.


Donc, du point de vue du langage, nous avons des classes avec le modificateur inline, qui sont traitées de manière spéciale par la machine virtuelle. Les instances de ces classes peuvent être incorporées dans d'autres objets, et des tableaux plats contenant des instances de classes en ligne sont également possibles. L'instance n'a pas d'en-tête, ce qui signifie qu'il n'y a pas d'identité, le code de hachage est calculé par champs, == également par champs, une tentative de synchronisation ou Object.wait() sur une telle classe lèvera une exception IllegalMonitorStateException. L'écriture de null dans une variable de ce type, bien sûr, ne fonctionnera pas. Cependant, les auteurs proposent une alternative: si vous avez déclaré un Point classe en ligne, vous pouvez alors déclarer un champ ou une variable de type (surprise-surprise!) Point? , puis il y aura un objet à part entière sur le tas (comme la boxe) avec un en-tête, une identité et une valeur null .


Les questions ouvertes sérieuses restent la spécialisation des génériques et la migration des classes existantes (par exemple, Optional ) vers une classe en ligne afin de ne pas casser le code existant (oui, les gens écrivent null dans des variables de type Optional ). Néanmoins, l'image se profile et l'écart est visible.


David Wrighton et Neal Gafter - Types de valeurs dans le CLR


Ce fut une surprise pour moi que le même Neil Gafter, co-auteur des puzzlers Java originaux, travaille maintenant chez Microsoft sur le runtime .Net. C'était également une surprise de voir un rapport sur le CLR (le soi-disant runtime .Net) sur la JVM LS. Mais se familiariser avec l'expérience de collègues d'autres mondes est toujours utile. Le rapport parle des variétés de références et de pointeurs dans le CLR, des instructions de bytecode utilisées pour les types de valeur et de la façon dont les fonctions généralisées magnifiquement spécialisées comme réduire. Il était intéressant d'apprendre que l'un des objectifs des types de valeur dans .Net est l'interopérabilité avec le code natif. Pour cette raison, l'emplacement des champs dans les types de valeur est strictement fixe et peut être projeté sur une structure sans transformations. La JVM n'a jamais eu une telle tâche, et quoi faire avec l'interopérabilité native - voir ci-dessous.


Vladimir Ivanov et John Rose - Vecteurs et numérique sur la JVM


Mettez à jour le rapport de l'an dernier . Encore une fois, la question est de savoir pourquoi ils n'ont toujours rien publié, alors qu'il y a un an, tout avait l'air plutôt bien.


Un vecteur est une collection de plusieurs nombres, qui dans le matériel peut être représenté par un seul registre vectoriel comme zmm0 pour AVX512. Dans les vecteurs, vous pouvez charger des données à partir de tableaux, effectuer des opérations sur celles-ci comme une multiplication par élément et les renvoyer. Toutes les opérations pour lesquelles il existe des instructions de processeur sont intégrées par le compilateur JIT dans ces instructions. Le nombre d'opérations est tout simplement énorme. Si quelque chose manque, une implémentation lente alternative est utilisée. Les objets vectoriels intermédiaires ne sont idéalement pas créés; l'analyse des échappements fonctionne. Tous les algorithmes informatiques standard sont vectorisés avec un bang, en utilisant toute la puissance de votre processeur.


Malheureusement, il est difficile pour les auteurs de ne pas avoir de valgalla: l'analyse d'échappement est fragile et peut ne pas fonctionner facilement. Ces vecteurs doivent simplement être des classes en ligne, puis tous les problèmes disparaîtront. On ne sait pas si cette API peut même être publiée avant la première version de Valgalla. Cela semble beaucoup plus prêt. Parmi les problèmes appelés difficultés avec le support du code. Il existe de nombreux éléments répétitifs pour différentes tailles de registres et différents types de données, de sorte que la plupart du code est généré à partir de modèles et qu'il est difficile de le maintenir.


L'utilisation est également imparfaite. Il n'y a pas de surcharge d'opérateur en Java, donc les mathématiques semblent laides: au lieu de max(va-vb*42, 0) vous devez écrire va.lanewise(SUB, vb.lanewise(MUL, 42)).lanewise(MAX, 0) . Ce serait bien d'avoir accès aux lambdas AST comme en C #. Il serait alors possible de générer une opération lambda personnalisée comme MYOP = binOp((va, vb) -> max(va-vb*42, 0)) et de l'utiliser.


30 juillet


Le deuxième jour s'est passé sous le pavillon de la compilation.


Mark Stoodley - De AOT à JIT et au-delà!


Un employé d'IBM, membre du projet JVM OpenJ9, parle de son expérience avec les compilations JIT et AOT. Il y a toujours des problèmes: JIT est un démarrage lent, car il se réchauffe; Coûts du processeur pour la compilation. AOT - performances sous-optimales en raison de l'absence de profil (il est possible de profiler, mais de manière non triviale et pas toujours le profil lors de la compilation correspond au profil lors de l'exécution), il est plus difficile à utiliser, se lier à la plate-forme cible, OS, garbage collector. Certains des problèmes peuvent être résolus en combinant des approches: en commençant par du code compilé par AOT puis en terminant par JIT. Une bonne alternative à tout cela est la mise en cache JIT. Si vous avez beaucoup de machines virtuelles (bonjour, microservices), elles se tournent toutes vers un service distinct - le compilateur JIT (oui, JITaaS), où tout est comme un adulte, l'orchestration, l'équilibrage de charge. Ce service se compile. Très souvent, il peut donner du code prêt à l'emploi à une certaine méthode, car cette méthode a déjà été compilée sur une autre JVM. Cela améliore considérablement l'échauffement, supprime la consommation de ressources de votre service JVM et réduit généralement la consommation totale de ressources.


En général, JITaaS pourrait être le prochain mot à la mode dans le monde JVM. Malheureusement, je n'ai pas compris si cela pouvait être joué en ce moment ou si c'est encore un développement fermé.


Christian Wimmer - Amélioration de l'image native GraalVM


GraalVM Native Image est une application Java compilée en code natif qui s'exécute sans JVM (contrairement aux modules compilés à l'aide d'un compilateur AOT comme jaotc). Plus précisément, ce n'est pas tout à fait une application Java. Pour fonctionner correctement, il a besoin d'un monde fermé, c'est-à-dire que tout le code doit être visible au stade de la compilation, pas Class.forName. Vous pouvez gérer les réflexions et les méthodes, mais lorsque vous compilez, vous devez indiquer précisément quelles classes et méthodes seront utilisées par le biais de la réflexion.


Une autre chose amusante est l'initialisation de classe. De nombreuses classes sont initialisées lors de la compilation. Autrement dit, vos champs statiques seront calculés par défaut par le compilateur et le résultat sera écrit dans l'image assemblée, et lorsque vous démarrez l'application, il est simplement lu. Ceci est nécessaire pour obtenir une meilleure qualité de compilation: tout pliage constant peut être effectué si les valeurs des champs statiques sont connues du compilateur. Tout va bien avec JIT, l'interpréteur effectue une initialisation statique, puis en connaissant les constantes, vous pouvez compiler. Et lors de la création d'une application native, vous devez tromper. Bien sûr, cela conduit à des effets psychédéliques amusants. Ainsi, les classes sont généralement initialisées dans l'ordre auquel elles sont accédées, et pendant la compilation, cet ordre est inconnu et l'initialisation dans un autre est possible. S'il existe des références circulaires entre les initialiseurs de classe, vous pouvez voir la différence dans le comportement du code JVM et dans l'image native.


Atelier Schatzl - Hotspot GC.


Trié toutes les douleurs associées aux récupérateurs. Malheureusement, j'ai écouté le plus. Je me souviens que le rappel de la mémoire du système d'exploitation a été discuté, y compris le Xmx dégoûtant pour tout le monde. Bonne nouvelle: dans Java 13, une nouvelle option -XX est ajoutée: SoftMaxHeapSize. Jusqu'à présent, il n'est pris en charge que par le collecteur ZGC, mais G1 peut également rattraper son retard. Il définit une limite sur la taille du tas, qui ne doit pas être dépassée, sauf dans les situations d'urgence, lorsqu'elle ne fonctionne pas différemment. Ainsi, vous pouvez définir un grand Xmx (par exemple, égal à la taille de la RAM entière) et un SoftMaxHeapSize raisonnable. Ensuite, la JVM se maintiendra la plupart du temps, mais à pleine charge, elle ne lancera toujours pas OutOfMemoryError, mais prendra plus de mémoire du système d'exploitation. Lorsque la charge diminue, la mémoire revient.


Mei-Chin Tsai - JIT et AOT dans le CLR


Microsoft Mei-Chin Tsai a parlé des fonctionnalités de la compilation JIT et AOT dans le CLR. La compilation AOT se développe pour eux depuis longtemps, mais initialement (ngen.exe) elle a été réalisée sur la plateforme cible, un peu comme la première fois qu'elle a démarré (si vous avez Windows, recherchez les fichiers * .ni.dll dans le dossier Windows). Les fichiers sont obtenus en fonction de la version de Windows local et même d'autres DLL-ek. Par conséquent, si la dépendance est mise à jour, tous les modules natifs doivent être recompilés. Dans la deuxième génération (crossgen), les auteurs ont précompilé des applications et des modules relativement indépendants des versions et des dépendances du matériel et du système d'exploitation. Cela a ralenti le code car les appels de dépendance devaient maintenant être rendus honnêtement virtuels. Ce problème a été résolu en connectant JIT et en recompilant le code actif lors de l'application. Ensuite, nous avons parlé de la compilation à plusieurs niveaux (à plusieurs niveaux) (il semble que dans le CLR, ce soit à ses balbutiements, alors qu'il se développe en Java depuis au moins dix ans) et des plans futurs pour faire d'AOT véritablement multiplateforme.


Wei Kuai et Xiaoming Gu - Accélérez les performances JVM avec JWarmUp


Des collègues d'Alibaba ont présenté leur approche du problème d'échauffement de la JVM. Ils utilisent la JVM pour de nombreux services Web. En principe, un démarrage très rapide n'est pas si important, car l'équilibreur peut toujours attendre que la machine démarre et ensuite seulement commencer à lui envoyer des requêtes. Cependant, le problème est que la machine ne chauffe pas sans requêtes: le code qui décrit la logique de traitement des requêtes n'est pas appelé, ce qui signifie qu'il ne compile pas. Il sera compilé lorsque les premières demandes arriveront, c'est-à-dire que peu importe le temps d'attente de l'équilibreur, il y aura un échec de performance sur les premières demandes. Auparavant, ils essayaient de résoudre ce problème en lançant de fausses demandes au service à venir avant de lui envoyer de vraies demandes. L'approche est intéressante, mais il est assez difficile de générer un tel faux flux qui provoquerait la compilation de tout le code nécessaire.


Un problème distinct est la désoptimisation. Dans les mille premières requêtes, une if toujours le long de la première branche, le compilateur JIT a généralement jeté la seconde, y insérant un piège de désoptimisation pour réduire la taille du code. Mais la 1001e demande est allée à la deuxième branche, la désoptimisation a fonctionné et toute la méthode est allée à l'interprète. Pendant que les statistiques sont à nouveau compilées, tandis que la méthode est compilée par le compilateur C1, puis par le profil complet par le compilateur C2, les utilisateurs connaîtront un ralentissement. Et puis dans la même méthode, un autre if peut être désoptimisé, et tout ira sur un nouveau.


JWarmUp résout le problème comme suit. Lors de la première exécution du service, un journal de compilation est écrit pendant plusieurs minutes: il enregistre les méthodes qui ont été compilées et les informations de profilage nécessaires par branches, types, etc. Si ce service est redémarré, immédiatement après le démarrage, toutes les classes du journal sont initialisées et les méthodes journalisées sont compilées en tenant compte du profil précédent. Par conséquent, le compilateur fonctionnera bien au démarrage, après quoi l'équilibreur commencera à envoyer des requêtes à cette machine virtuelle Java. À ce moment, tout le code chaud qu'elle a déjà été compilé.


Il convient de noter que le problème de démarrage rapide n'est pas résolu ici. Un lancement peut être encore plus lent car de nombreuses méthodes sont compilées, dont certaines peuvent être nécessaires seulement quelques minutes après le lancement. Mais le journal se révèle réutilisable: contrairement à AOT, vous pouvez augmenter le service sur une architecture différente ou avec un garbage collector différent et réutiliser le journal précédent.


Les auteurs tentent depuis longtemps de pousser JWarmUp dans OpenJDK. Jusqu'à présent sans succès, mais le travail avance. L'essentiel est qu'un correctif à part entière soit assez accessible pour vous-même sur le serveur Code Review, vous pouvez donc facilement l'appliquer aux sources HotSpot et créer la JVM vous-même avec JWarmUp.


Juan Fumero - TornadoVM


Il s'agit d'un document de recherche de Manchester, mais les auteurs affirment que le projet a déjà été mis en œuvre à certains endroits. C'est également un module complémentaire pour OpenJDK, ce qui facilite le transfert de certains codes Java vers GPU, iGPU, FPGA ou simplement le parallélise aux cœurs de son processeur. Pour compiler sur le GPU, ils utilisent GraalVM dans lequel ils ont construit leur backend - TornadoJIT. Une méthode Java correctement écrite va de manière transparente vers le périphérique correspondant. Certes, ils disent que la compilation sur FPGA peut prendre plusieurs heures, mais si votre tâche est considérée comme un mois, alors pourquoi pas. Certains benchmarks (par exemple, la transformée de Fourier discrète) sont plus de cent fois plus rapides que le Java brut, ce qui est prévu en principe. Le projet est entièrement téléchargé sur GitHub , où vous pouvez également trouver des publications scientifiques sur le sujet.


Maurizio Cimadomore - Déconstruire le Panama


Tous la même chanson - un projet de longue date, chaque présentation au sommet, il y a un an, tout semblait assez prêt, mais il n'y avait toujours pas de sortie. Il s'est avéré que depuis lors, la focalisation a changé.


L'idée du projet est une interface améliorée avec du code natif. Tout le monde sait combien il est douloureux d'utiliser JNI. Ça fait vraiment mal. Le projet Panama annule cette douleur: l'utilisation de classes Java jextract est générée à partir des fichiers * .h de la bibliothèque native, qui sont assez pratiques à utiliser en appelant des méthodes natives. Côté C / C ++, vous n'avez pas du tout besoin d'écrire une seule ligne. De plus, tout est devenu beaucoup plus rapide: les frais généraux sur les appels vers Java-> natif et natif-> Java ont parfois baissé. Que voulez-vous de plus?


Il y a un problème qui existe depuis un certain temps - le transfert de tableaux de données en code natif. Jusqu'à présent, la méthode recommandée est DirectByteBuffer, qui a beaucoup de problèmes. L'une des plus graves est la durée de vie non gérée (le tampon disparaîtra lorsque le garbage collector récupérera l'objet Java approprié). À cause de cela et d'autres problèmes, les gens utilisent Unsafe qui, avec une diligence raisonnable, peut facilement déposer l'ensemble de la machine virtuelle.


Cela signifie que vous avez besoin d'un nouvel accès mémoire normal en dehors du tas Java. Allocation, accesseurs structurés, suppression explicite. Accesseurs structurés - pour que vous n'ayez pas à calculer vous-même les décalages si vous avez besoin d'écrire, par exemple, struct { byte x; int y; }[5] struct { byte x; int y; }[5] struct { byte x; int y; }[5] . Au lieu de cela, vous décrivez une fois la disposition de cette structure, puis faites, par exemple, VarHandle , qui peut lire tous les x en sautant par-dessus y . Dans ce cas, bien sûr, il devrait toujours y avoir une vérification des frontières, comme dans les tableaux Java ordinaires. En outre, l'accès à une zone déjà fermée devrait être interdit. Et cela s'avère être une tâche non triviale si nous voulons maintenir les performances au niveau dangereux et permettre l'accès à partir de plusieurs threads. Bref, regardez la vidéo, très intéressante.


Atelier: Vladimir Kozlov - Projet Metropolis


Le projet Metropolis combine toutes les tentatives de réécriture de parties de la JVM en Java. Sa partie principale aujourd'hui est le compilateur Graal. Ces dernières années, il s'est très bien développé et il est déjà question d'un remplacement complet du C2 vieillissant. Autrefois, il y avait un problème de bootstrap: le Graal a commencé lentement, car lui-même devait être compilé en JIT ou interprété. Puis la compilation AOT est apparue (oui, l'objectif principal du projet de compilation AOT est le bootstrap du graal lui-même). Mais avec AOT, le Graal mange une partie décente du tas d'une application Java qui peut ne pas vraiment vouloir partager son tas. Nous avons maintenant appris à transformer le Graal en une bibliothèque native en utilisant Graal Native Image, ce qui nous a finalement permis d'isoler le compilateur du tas général. Avec les performances de pointe du code compilé par le Graal, il y a encore des problèmes sur certains benchmarks. Par exemple, le Graal est en retard sur C2 en intrinsèque et en vectorisation. Cependant, grâce à l'analyse d'inline et d'échappement très puissante, il casse simplement C2 sur le code fonctionnel, où de nombreux objets immuables et de nombreuses petites fonctions sont créés. Si vous écrivez sur le Rocher et que vous n'utilisez toujours pas le Graal, courez pour l'utiliser. De plus, dans les dernières versions de JDK, il est assez banal de faire quelques clés, tout est déjà dans le kit.


31 juillet


Kevin Bourrillion - Annotations de nullité pour Java


Kevin a annoncé un nouveau projet, mais a demandé à ne pas parler publiquement et à ne pas publier un enregistrement de son discours sur YouTube. Désolé. , .


Dmitry Petrashko — Gradual typing for Ruby at Scale with Sorbet


Sorbet (!) Ruby, Ruby . , Stripe Ruby , , . , .


Lightning Talks


- . Remi Forax , , . , :



, - , .


Erik Meijer — Differentiable Programming


ML AI , . , Facebook — getafix , --, , . . , , . , , .


. . OpenJDK Committer Workshop.

Source: https://habr.com/ru/post/fr462101/


All Articles