Chaînes compactes dans Java 9

Bonjour encore! Nous avons ouvert le prochain ensemble dans le, maintenant le neuvième, groupe «Java Developer» (et le dixième groupe dans les plans, tout à coup, se tient le 31 décembre) et avons préparé du matériel intéressant et une leçon ouverte pour vous.

Alors allons-y.

Vous souhaitez réduire la quantité de mémoire utilisée par votre application Java? Découvrez comment vous pouvez améliorer les performances avec les chaînes compactes disponibles dans Java 9.

L'une des améliorations de performances introduites dans la JVM (Oracle HotSpot, pour être précis), dans le cadre de Java SE 9, s'est avérée être des chaînes compactes. Leur tâche est de réduire la taille des objets String, ce qui permet de réduire la quantité totale (encombrement) de mémoire consommée par l'application. Par conséquent, cela peut réduire le temps consacré à la collecte des ordures.



La fonction est basée sur l'observation que de nombreux objets String n'ont pas besoin de 2 octets pour coder chaque caractère, car la plupart des applications utilisent uniquement des caractères Latin-1. Par conséquent, au lieu de cela:

/**       */ private final char value[]; 

Dans java.lang.String maintenant ceci:

 private final byte[] value; /** *        * {@code value}.      : * * LATIN1 * UTF16 * * @implNote     .    * “”,   String - .   *      . */ private final byte coder; 

En d'autres termes, cette fonction remplace la valeur dans le tableau de caractères (où chaque élément utilise 2 octets) par un tableau d'octets avec un octet supplémentaire pour déterminer le codage (Latin-1 ou UTF-16). Cela signifie que dans la plupart des applications utilisant uniquement des caractères Latin-1, seule la moitié du segment sera utilisée. L'utilisateur ne remarquera pas les différences, mais les API associées, telles que StringBuilder , en profiteront automatiquement.

Pour montrer ce changement en termes de taille de l'objet String, j'utiliserai Java Object Layout, un utilitaire simple pour visualiser la structure de l'objet sur le tas. De ce point de vue, nous nous intéressons à l'encombrement du tableau (stocké dans la variable de valeur ci-dessus), et pas seulement à une référence (une référence de tableau d'octets, comme une référence de tableau de caractères, utilise 4 octets). Le code ci-dessous affiche les informations à l'aide de JOL GraphLayout :

 public class JOLSample { public static void main(String[] args) { System.out.println(GraphLayout.parseInstance("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz").toFootprint()); } } le public class JOLSample { public static void main(String[] args) { System.out.println(GraphLayout.parseInstance("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz").toFootprint()); } } ) ToFootprint ()); public class JOLSample { public static void main(String[] args) { System.out.println(GraphLayout.parseInstance("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz").toFootprint()); } } 

L'exécution du code ci-dessus dans Java 8 puis dans Java 9 montre la différence:

 $java -version java version "1.8.0_121" Java(TM) SE Runtime Environment (build 1.8.0_121-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode) $java -cp lib\jol-cli-0.9-full.jar;. test.JOLSample java.lang.String@4554617cd footprint: COUNT AVG SUM DESCRIPTION 1 432 432 [C 1 24 24 java.lang.String 2 456 (total) ... $java -version java version "9" Java(TM) SE Runtime Environment (build 9+181) Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode) $java -cp lib\jol-cli-0.9-full.jar;. test.JOLSample java.lang.String@73035e27d footprint: COUNT AVG SUM DESCRIPTION 1 224 224 [B 1 24 24 java.lang.String 2 248 (total) 

En ignorant la taille de 24 octets des composants internes de java.lang.String (en-tête plus liens), nous constatons qu'en raison de sa compacité, la taille a diminué de près de moitié.
Si nous remplaçons la ligne ci-dessus par une autre utilisant des caractères UTF-16, par exemple \ u0780, puis redémarrons le code ci-dessus, alors Java 8 et Java 9 afficheront la même empreinte, car la compacité ne sera plus utilisée.

Vous pouvez désactiver cette fonction en transmettant le -XX:-CompactStrings à la commande java .

Comme toujours, nous attendons vos commentaires et questions ici, ainsi que vous invitons à une leçon ouverte .

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


All Articles