JavaRush /Blog Java /Random-FR /Du 8 au 13 : un aperçu complet des versions Java. Partie ...

Du 8 au 13 : un aperçu complet des versions Java. Partie 2

Publié dans le groupe Random-FR
Cet article est la deuxième partie de ma revue des innovations des versions Java 8-13. La première partie est ici . Sans plus attendre, passons à autre chose : au 25 septembre 2018, date de sortie du nouveau JDK :

Java11

Du 8 au 13 : un aperçu complet des versions Java.  Partie 2 - 1

var (en lambda)

Désormais, nous pouvons spécifier les types de paramètres lambda ou les omettre lors de l'écriture d'une expression lambda (expressions lambda implicitement typées) :
Function<String, String> append = (var string) -> string + " Text";
String appendedString = append.apply("Some");
System.out.println(appendedString);
Vous pouvez également ajouter des annotations aux paramètres lambda sans avoir à écrire le nom complet du type de variable :
Function<String, String> append = (@NonNull var string) -> string + " Text";

Z(ZGC)

ZGC est un nouveau garbage collector qui ne fonctionne pas. Il alloue une nouvelle mémoire mais ne la redémarre jamais. ZGC promet de gérer de grandes quantités de mémoire avec un débit élevé et une faible latence (ZGC n'est disponible que sur les plateformes 64 bits). Coloration de référence - ZGC utilise des pointeurs 64 bits avec une technique appelée coloration du pointeur. Les pointeurs colorés stockent des informations supplémentaires sur les objets sur le tas. Lorsque la mémoire est fragmentée, cela permet d'éviter une dégradation des performances lorsque le GC doit trouver de la place pour une nouvelle allocation. La collecte des déchets à l'aide de ZGC comprend les étapes suivantes :
  1. le monde s'arrête : nous recherchons des points de départ pour atteindre les objets sur le tas (comme des variables locales ou des champs statiques) ;
  2. intersection de graphes d'objets à partir des liens racines. Nous marquons chaque objet que nous atteignons (ZGC parcourt le graphique des objets et examine les marqueurs colorés, marquant les objets disponibles) ;
  3. gérer certains cas extrêmes, tels que les liens faibles ;
  4. déplacer des objets vivants, libérant de grandes zones du tas pour accélérer l'allocation.
  5. lorsque la phase de déplacement commence, ZGC divise le tas en pages et travaille une page à la fois ;
  6. Le ZGC termine le mouvement de toutes les racines et le reste du mouvement se produit.
Ce sujet est très complexe et déroutant. Une discussion détaillée nécessiterait un article séparé, je vais donc le laisser ici :

EpsilonGC

Epsilon est un garbage collector qui gère l'allocation de mémoire mais n'implémente aucun véritable mécanisme de récupération de mémoire. Une fois le tas Java disponible épuisé, la JVM s'arrêtera. Autrement dit, si vous commencez à créer un objet dans un tableau infini sans vous lier à une référence avec ce garbage collector, l'application plantera avec une OutOfMemoryError (et si avec un autre, elle ne le fera pas, car elle nettoiera les objets sans références) . Pourquoi est-ce nécessaire ? Voici pourquoi:
  1. Test de performance.
  2. Test de pression de mémoire.
  3. Test de l'interface de la VM.
  4. Travail extrêmement court.
  5. Améliorations de la latence de dernière goutte.
  6. Améliorations du débit de dernière goutte.
Liens utiles: Autres nouveautés :
  1. ByteArrayOutputStreamJ'ai une méthode void writeBytes(byte [])qui écrit tous les octets de l'argument dans OutputStream.
  2. FileReaderet FileWriterj'ai obtenu de nouveaux constructeurs qui vous permettent de spécifier Charset.
  3. Pathsaisi deux nouvelles méthodes, of(String, String [])renvoie Pathà partir d'un argument de chaîne un chemin ou une séquence de chaînes qui, une fois combinées, forment une chaîne de chemin et of(URI): renvoie le chemin à partir d'un URI.
  4. Pattern— a reçu une méthode asMatchPredicate()qui vérifie si une chaîne d'entrée donnée correspond à un modèle donné (si elle vous permet de créer un prédicat à l'aide d'une expression régulière afin que vous puissiez, par exemple, filtrer les données dans un flux).
  5. StringJ'ai choisi de nombreuses méthodes utiles, telles que :
    • String strip(): nous renverra une chaîne qui est cette chaîne, avec tous les espaces au début et à la fin de la chaîne supprimés (similaire à trim(), mais définit les espaces différemment) ;
    • String stripLeading(): nous renverra la chaîne qui est cette chaîne, en supprimant tous les espaces de début de la chaîne ;
    • String stripTrailing(): nous renverra la chaîne qui est cette chaîne, en supprimant tous les espaces à la fin de la chaîne ;
    • Stream lines(): nous renverra Streamfrom String, extrait de cette chaîne, séparé par des séparateurs de ligne ;
    • String repeat(int): nous renverra une chaîne qui est une concaténation de cette chaîne, répétée plusieurs fois.
    • boolean isBlank(): renverra true si la chaîne est vide ou ne contient que des espaces, false sinon.
  6. Thread— les méthodes destroy() et stop(Throwable) ont été supprimées.
  7. Filesa un certain nombre de nouvelles méthodes:
    • String readString(Path): lit toutes les données d'un fichier dans une chaîne, tout en décodant des octets en caractères à l'aide du codage UTF-8 ;
    • String readString(Path, Charset): identique à la méthode ci-dessus, à la différence que le décodage des octets en caractères s'effectue à l'aide du jeu de caractères spécifié ;
    • Path writeString (Path, CharSequence, OpenOption []): Écrit une séquence de caractères dans un fichier. Les caractères sont codés en octets à l'aide du codage UTF-8 ;
    • Path writeString(Path, CharSequence,Charset, OpenOption []): Même méthode que ci-dessus, seuls les caractères sont codés en octets en utilisant le codage spécifié dans Charset.
Ce sont les innovations API les plus intéressantes (à mon humble avis), voici quelques documents pour un examen plus détaillé :

Java12

Six mois s'écoulent et nous voyons la prochaine étape dans l'évolution de Java. Il est donc temps de sortir une pelle de connaissances et de creuser. Du 8 au 13 : un aperçu complet des versions Java.  Partie 2 - 2

Mise à jour G1

Les améliorations suivantes ont été apportées pour G1 :
  1. Récupérer la mémoire allouée inutilisée

    Dans la mémoire de tas Java, il existe une mémoire inutilisée (ou en d'autres termes, inactive). Dans Java 12, ils ont décidé de résoudre ce problème, maintenant :

    • G1 renvoie la mémoire du tas dans un GC complet ou lors d'une boucle parallèle ; G1 essaie d'empêcher un GC complet et démarre une boucle parallèle basée sur l'allocation du tas. Nous devrons forcer G1 à restituer la mémoire du tas.

    Cette amélioration se concentre sur les performances en renvoyant automatiquement la mémoire du tas vers le système d'exploitation lorsque le G1 n'est pas utilisé.

  2. Abandon des collections mixtes lorsque le temps de pause est dépassé

    G1 utilise un moteur d'analyse pour sélectionner la quantité de travail requise pour le garbage collection. Il collecte les objets vivants sans s'arrêter après avoir défini l'ensemble et démarré le nettoyage. Cela amène le ramasse-miettes à dépasser son objectif de temps de pause. En fait, ce problème est résolu par l'amélioration, puisque si le temps nécessaire pour réaliser l'étape suivante dépasse les limites raisonnables, cette étape peut être interrompue.

Microbenchmark

Java 12 a introduit des tests de microbenchmarking afin que les performances de la JVM puissent être facilement testées à l'aide des tests de référence existants. Cela serait très utile pour quiconque souhaite travailler sur la JVM elle-même. Les tests ajoutés sont créés à l'aide de Java Microbenchmark Harness (JMH). Ces tests permettent de tester en continu les performances de la JVM. JEP 230 propose l'introduction d'environ 100 tests, avec de nouveaux tests introduits à mesure que de nouvelles versions de Java sont publiées. Voici un exemple des tests ajoutés .

Shenandoah

Il s'agit d'un algorithme de garbage collection (GC) qui vise à garantir des temps de réponse faibles (la limite inférieure est de 10 à 500 ms). Cela réduit le temps de pause du GC lors du travail de nettoyage en même temps que l'exécution des threads Java. Dans Shenandoah, le temps de pause est indépendant de la taille du tas. Cela signifie que le temps de pause sera le même quelle que soit la taille de votre tas. Il s'agit d'une fonctionnalité expérimentale et n'est pas incluse dans la version standard (Oracle) d'OpenJDK.

Améliorer le commutateur

Java 12 a amélioré les expressions Switch pour la correspondance de modèles. Une nouvelle syntaxe L → a été introduite. Voici une liste des points clés du nouveau switch :
  1. La nouvelle syntaxe élimine le besoin d'une instruction break pour éviter les erreurs.
  2. Les expressions de commutation n’échouent plus.
  3. De plus, nous pouvons définir plusieurs constantes dans une seule étiquette.
  4. la casse par défaut est désormais requise dans les expressions switch.
  5. break est utilisé dans les expressions Switch pour renvoyer les valeurs du registre lui-même (en fait, un switch peut renvoyer des valeurs).
Regardons ceci à titre d'exemple :
var result = switch (someDay) {
  case "M", "W", "F" -> "MWF";
  case "T", "TH", "S" -> "TTS";
  default -> {
      if(someDay.isEmpty())
            break "Please insert a valid day.";
      else
            break "Looks like a Sunday.";
  }
};
Guide définitif pour changer d'expression en Java 13 Autres nouvelles fonctionnalités :
  1. String:

    transform(Function f)- Applique la fonction fournie à une chaîne. Le résultat ne peut pas être une chaîne.
    indent(int x)— ajoute x espaces à la chaîne. Si le paramètre est négatif, alors ce nombre d'espaces de début sera supprimé (si possible).

  2. Files- saisi une méthode comme mismatch(), qui, à son tour, trouve et renvoie la position du premier octet incompatible dans le contenu de deux fichiers, ou -1L s'il n'y a pas d'incompatibilité.

  3. Une nouvelle classe est apparue :CompactNumberFormat pour formater un nombre décimal sous une forme compacte. Un exemple de cette forme compacte est 1M au lieu de 1 000 000. Ainsi, seuls deux deux sont requis au lieu de neuf caractères.

  4. Il y en a aussi un nouveau enum , NumberFormatStylequi a deux valeurs - LONG et SHORT.

  5. InputStream j'ai obtenu la méthode skipNBytes(long n) : ignorez le nième nombre d'octets du flux d'entrée.

Liens Java 12 intéressants :

Java13

Le monde ne reste pas immobile, il bouge, il se développe, tout comme Java - Java 13. Du 8 au 13 : un aperçu complet des versions Java.  Partie 2 - 3

Bloc de texte

Java a toujours un peu souffert lorsqu'il s'agissait de définir des chaînes. Si nous devions définir une ligne avec un espace, un saut de ligne, une citation ou autre chose, cela posait quelques difficultés, nous devions donc utiliser des caractères spéciaux : par exemple, \n pour un saut de ligne, ou un échappement d'une partie de la ligne. lui-même. Cela réduit considérablement la lisibilité du code et prend plus de temps lors de l'écriture d'une telle ligne. Cela devient particulièrement visible lors de l'écriture de chaînes affichant JSON, XML, HTML, etc. En conséquence, si nous voulons écrire un petit Json, il ressemblera à ceci :
String JSON_STRING = "{\r\n" + "\"name\" : \"someName\",\r\n" + "\"site\" : \"https://www.someSite.com/\"\r\n" + "}";
Et puis Java 13 entre en scène et nous propose sa solution sous la forme de triples guillemets doubles avant et après le texte (qu'ils appelaient des blocs de texte). Regardons l'exemple json précédent utilisant cette innovation :
String TEXT_BLOCK_JSON = """
{
    "name" : "someName",
    "site" : "https://www.someSite.com/"
}
""";
C'est beaucoup plus simple et clair, n'est-ce pas ? StringTrois nouvelles méthodes ont également été ajoutées respectivement pour gérer ces blocs :
  • stripIndent(): Supprime les espaces aléatoires d'une chaîne. Ceci est utile si vous lisez des chaînes multilignes et souhaitez appliquer le même type d'exclusion d'espaces aléatoires qui se produit avec une déclaration explicite (simulant essentiellement le compilateur pour supprimer les espaces aléatoires) ;
  • formatted(Object... args ): similaire à format(String format, Object... arg), mais pour les blocs de texte ;
  • translateEscapes(): renvoie une chaîne avec des séquences d'échappement (telles que \r) traduites en valeur Unicode correspondante.

Améliorer le commutateur

Les expressions Switch ont été introduites dans Java 12 et 13 les affine. En 12, vous définissez les valeurs de retour en utilisant break. En 13, la valeur de retour a été remplacée par le rendement. Maintenant, l'expression switch que nous avions dans la section Java 12 peut être réécrite comme suit :
var result = switch (someDay) {
  case "M", "W", "F" -> "MWF";
  case "T", "TH", "S" -> "TTS";
  default -> {
      if(someDay.isEmpty())
          yield "Please insert a valid day.";
      else
          yield "Looks like a Sunday.";
  }
};
Même s'il était normal que nous, programmeurs déjà familiers avec Java, acceptions de faire des pauses, c'était néanmoins assez étrange. Qu'est-ce que Break True essaie de me dire ? Le nouveau mot-clé de rendement (relativement nouveau) est plus clair et peut apparaître à l'avenir à d'autres endroits où les valeurs sont renvoyées. Pour ceux qui sont profondément intéressés par ce sujet, je vous recommande de vous familiariser avec ces documents :

Archives CDS dynamiques

CDS - Partage de données de classe. Vous permet de regrouper un ensemble de classes couramment utilisées dans une archive qui peut ensuite être chargée par plusieurs instances JVM. Pourquoi avons nous besoin de ça? Le fait est que lors du chargement des classes, la JVM effectue de nombreuses actions gourmandes en ressources, telles que lire les classes, les stocker dans des structures internes, vérifier l'exactitude des classes lues, rechercher et charger des classes dépendantes, etc. ., et seulement après tout cela, les classes sont prêtes à travailler. Naturellement, beaucoup de ressources sont gaspillées, puisque les instances JVM peuvent souvent charger les mêmes classes. Par exemple String, LinckedList, Integer. Eh bien, ou des classes de la même application, et toutes ces ressources sont des ressources. Si nous effectuions toutes les étapes nécessaires une seule fois, puis placions les classes repensées dans une archive pouvant être chargée dans la mémoire de plusieurs JVM, cela pourrait considérablement économiser de l'espace mémoire et réduire le temps de démarrage des applications. En fait, CDS permet précisément de créer une telle archive. Java 9 autorisait uniquement l'ajout de classes système à l'archive. Java 10 - inclut les classes d'application dans l'archive. La création d'une telle archive consiste à :
  • créer une liste de classes chargées par l'application ;
  • créer une archive indispensable avec les classes que nous avons trouvées.
L'innovation de Java 13 améliore CDS afin qu'il puisse créer une archive à la fin de l'application. Cela signifie que les deux étapes ci-dessus seront désormais combinées en une seule. Et encore un point important : seules les classes chargées pendant l'exécution de l'application seront ajoutées à l'archive. En d'autres termes, les classes qui sont toujours contenues dans application.jar, mais qui, pour une raison quelconque, n'ont pas été chargées, ne seront pas ajoutées à l'archive.

Mettre à jour l'API de socket

L'API Socket ( java.net.Socket et java.net.ServerSocket ) fait essentiellement partie intégrante de Java depuis sa création, mais les sockets n'ont jamais été mis à jour au cours des vingt dernières années. Écrits en C et Java, ils étaient très, très volumineux et difficiles à maintenir. Mais Java 13 a décidé de faire ses propres ajustements sur toute cette question et a remplacé l'implémentation de base. Désormais, au lieu de PlainSocketImpl, l'interface du fournisseur est remplacée par NioSocketImpl . Cette nouvelle implémentation codée est basée sur la même infrastructure back-end que java.nio . Essentiellement, la classe utilise le cache de tampon java.util.concurrent et le mécanisme de verrouillage (qui sont basés sur des segments) plutôt que des méthodes synchronisées. Il ne nécessite plus de code natif, ce qui facilite le portage sur différentes plateformes. Néanmoins, nous avons un moyen de revenir à l'utilisation de PlainSocketImpl , mais à partir de maintenant, NioSocketImpl est utilisé par défaut .

Retour de mémoire pour ZGC

Comme nous nous en souvenons, le garbage collector Z a été introduit dans Java 11 en tant que mécanisme de garbage collection à faible latence afin que la pause GC ne dépasse jamais 10 ms. Mais en même temps, contrairement à d’autres HotSpots virtuels GC, tels que Shenandoah et G1, il pourrait restituer la mémoire dynamique inutilisée au système d’exploitation. Cette modification ajoute cette capacité J à ZGC. En conséquence, nous obtenons une empreinte mémoire réduite ainsi que des performances améliorées, et ZGC renvoie désormais par défaut la mémoire non allouée au système d'exploitation jusqu'à ce que la taille minimale du tas spécifiée soit atteinte. Encore une chose : ZGC a désormais une taille de tas maximale prise en charge de 16 To. Auparavant, 4 To était la limite. Autres nouveautés :
  1. javax.security- ajout d'une propriété jdk.sasl.disabledMechanismspour désactiver les mécanismes SASL.
  2. java.nio- une méthode a été ajoutée FileSystems.newFileSystem (Path, Map <String,?>)- respectivement, pour créer un nouveau fichier.
  3. Les classes java.nioont désormais des méthodes absolues (par opposition à relatives) getet set-. Comme la classe abstraite de base, elles Bufferincluent une méthode slice()pour récupérer une partie du tampon.
  4. Ajout javax.xml.parsersde méthodes pour instancier les usines DOM et SAX (avec prise en charge des espaces de noms).
  5. La prise en charge d'Unicode a été mise à jour vers la version 12.1.
Liens intéressants sur Java 13 :

Résultats

Nous pourrions passer en revue les innovations annoncées dans Java 14, mais comme il verra le jour très prochainement - la sortie du JDK 14 est prévue pour le 17 mars 2020, il serait préférable d'en procéder à une révision séparée et complète immédiatement après sa sortie. . Je voudrais également attirer votre attention sur le fait que dans d'autres langages de programmation avec de longues pauses entre les versions, comme Python 2-3, il n'y a pas de compatibilité : c'est-à-dire que si le code est écrit en Python 2, vous le ferez il faut travailler dur pour le traduire en 3. Java est spécial à cet égard car il est extrêmement rétrocompatible. Cela signifie que votre programme Java 5 ou 8 est assuré de s'exécuter sur une machine virtuelle Java 8-13, à quelques exceptions près dont vous n'avez pas à vous soucier pour l'instant. Il est clair que cela ne fonctionne pas dans l'autre sens : par exemple, si votre application utilise des fonctions Java 13 qui ne sont tout simplement pas disponibles dans la JVM Java 8. C'est tout pour moi aujourd'hui, respect à ceux qui ont lu jusqu'ici)) Du 8 au 13 : un aperçu complet des versions Java.  Partie 2 à 5
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION