Pool constant de cordes en java
Il existe deux formes de création d'objets de chaîne dans Java. L'une est une forme littérale, comme la chaîne str = "droid"; et l'autre est une méthode standard de construction d'objets en utilisant de nouvelles, telles que String str = new String ("Droid");. Nous utilisons souvent ces deux méthodes lors de l'écriture de code, en particulier la méthode littérale. Cependant, ces deux implémentations ont en fait des différences dans les performances et l'utilisation de la mémoire. Tout cela est dû au fait que le JVM maintient une mémoire spéciale afin de réduire la création répétée d'objets de chaîne, qui est un pool de chaînes de chaîne ou un pool littéral de chaîne.
Comment ça marche
Lorsqu'un objet String est créé dans le formulaire littéral dans le code, le JVM vérifie d'abord le littéral. S'il y a une référence à un objet String avec le même contenu dans le pool de string constant, la référence sera renvoyée. Sinon, le nouvel objet String sera créé, puis la référence sera placée dans le pool constant de chaîne et la référence sera retournée.
Donner un exemple
Forme de création littérale
String str1 = "droid";
JVM détecte ce littéral, nous pensons ici qu'aucun objet avec le contenu n'est droïde n'existe. Le JVM ne peut pas trouver l'objet String avec du contenu DROID via le pool de constante de chaîne, donc il créera cet objet String, puis mettra la référence de l'objet que vous venez de créer dans le pool constant de chaîne, et renvoie la référence à la variable STR1.
S'il y a un code comme celui-ci
String str2 = "Droid";
De même, le JVM doit encore détecter ce littéral. En recherchant le pool constant de chaîne, le JVM a constaté que le contenu est un objet de chaîne "Droid" existe, il renvoie donc la référence de l'objet de chaîne existant à la variable STR2. Notez que les nouveaux objets String ne seront pas recréés ici.
Vérifiez si STR1 et STR2 pointent vers le même objet, nous pouvons utiliser ce code
System.out.println (str1 == str2);
Le résultat est vrai.
Créer avec nouveau
String str3 = new String ("Droid");
Lorsque nous utilisons New pour construire des objets String, de nouveaux objets String seront créés, qu'il existe des références à des objets avec le même contenu dans le pool constant de chaîne. Alors utilisons le code suivant pour le tester.
String str3 = new String ("Droid");
System.out.println (str1 == str3);
Le résultat est faux comme nous le pensons, indiquant que les deux variables pointent vers différents objets.
interne
Pour l'objet String créé avec nouveau ci-dessus, si vous souhaitez ajouter une référence au pool de constante de chaîne, vous pouvez utiliser la méthode interne.
Après avoir appelé Intern, vérifiez d'abord s'il y a une référence à l'objet dans le pool constant de chaîne. S'il existe, retournez cette référence à la variable, sinon la référence sera ajoutée et retournée à la variable.
String str4 = str3.intern ();
System.out.println (str4 == str1);
Le résultat de sortie est vrai.
Problèmes difficiles
Prérequis?
La condition préalable à la mise en œuvre des pools constantes de chaîne est que les objets de chaîne en Java sont immuables, ce qui peut garantir en toute sécurité que plusieurs variables partagent le même objet. Si l'objet String en Java est variable et qu'une opération de référence modifie la valeur de l'objet, d'autres variables seront également affectées, ce qui est évidemment déraisonnable.
Référence ou objet
Cette question est la plus courante lorsqu'un pool constant de chaîne est stocké dans une référence ou un objet. Le pool constant string stocke les références d'objets, pas les objets. En Java, les objets sont créés dans la mémoire du tas.
Mettre à jour la vérification, de nombreux commentaires reçus discutent également de ce problème, et je le vérifie simplement. Vérifiez l'environnement
22: 18: 54-Androidyue ~ / Videos $ Cat / etc / OS-Releasename = Fedoraversion = "17 (Boevey Miracle)" ID = Fedoraversion_ID = 17PRETTY_NAME = "Fedora 17 (Beefy Miracle) "ANSI_COLOR =" 0; 34 "CPE_NAME =" CPE: / O: Fedoraproject: Fedora: 17 "22: 19: 04-Androidyue ~ / Videos $ Java -VersionJava version" 1.7.0_25 "OpenJDK Runtime Environ VM (build 23,7-b01, mode mixte)
Idée de vérification: le programme Java suivant lit un fichier vidéo de la taille de 82 m et effectue des opérations internes sous la forme d'une chaîne.
22: 01: 17 androidyue ~ / vidéos $ ll -lh | grep why_to_learn.mp4-rw-rw-r--. 1 Androidyue Androidyue 82m 20 oct 2013 Why_To_Learn.mp4
Le code de vérification
Importer java.io.bufferedReader; import java.io.filenotfoundException; import java.io.fileReader; import java.io.ioException; public class testmain {private static string fileContent; public static void main (String [] args) {fileContent = readFileToString (args [0]); if (null! = fileContent) {fileContent = fileContent.intern (); System.out.println ("Not Null"); }} chaîne statique privée readFileToString (file de chaîne) {BufferedReader Reader = null; try {Reader = new BufferedReader (new FileReader (fichier)); StringBuffer buff = new StringBuffer (); Ligne de chaîne; while ((line = reader.readline ())! = null) {buff.append (line); } return buff.toString (); } catch (filenotFoundException e) {e.printStackTrace (); } catch (ioException e) {e.printStackTrace (); } enfin {if (null! = lecteur) {try {reader.close (); } catch (ioException e) {e.printStackTrace (); }}} return null; }}Étant donné que le pool constant de chaîne existe dans la génération permanente dans la mémoire du tas, il convient avant Java 8. Nous vérifions en définissant une génération permanente d'une petite valeur. Si l'objet String existe dans le pool constant de chaîne, une erreur d'espace java.lang.outofMemoryError Permgen doit être lancée.
java -xx: permsize = 6m testmain ~ / vidéos / why_to_learn.mp4
L'exécution du programme de preuve ne lance pas OOM, mais cela ne peut pas prouver qu'il est stocké comme un objet ou une référence.
Mais cela prouve au moins que le char [] de l'objet de contenu réel de la chaîne n'est pas stocké dans le pool constant de chaîne. Dans ce cas, il n'est pas si important que le pool constant de chaîne stocke les références aux objets de chaîne ou aux objets String. Mais les individus ont toujours tendance à stocker des références.
Pour les avantages et les inconvénients
L'avantage de la mise en commun constante des cordes est de réduire la création de chaînes du même contenu et de sauvegarder l'espace mémoire.
Si vous devez dire les inconvénients, c'est pour sacrifier le temps de calcul du processeur pour échanger de l'espace. Le temps de calcul du CPU est principalement utilisé pour découvrir s'il existe des références aux objets avec le même contenu dans le pool constant de chaîne. Cependant, sa mise en œuvre interne est de hachage, donc le coût de calcul est faible.
Recyclage GC?
Étant donné que le pool constant de chaîne détient une référence à l'objet de chaîne partagé, cela signifie-t-il que ces objets ne peuvent pas être recyclés?
Tout d'abord, les objets partagés dans la question sont généralement plus petits. Pour autant que je sois vérifié, il y avait en effet un tel problème dans les versions antérieures, mais avec l'introduction de références faibles, ce problème devrait être parti à l'heure actuelle.
En ce qui concerne ce problème, vous pouvez en savoir plus sur cet article. Cordons internés: Glossaire Java
Utiliser Intern?
La condition préalable à l'utilisation de Stanse est que vous savez que vous devez vraiment l'utiliser. Par exemple, nous avons un dossier de millions ici, où une certaine valeur du dossier est la Californie, les États-Unis à plusieurs reprises. Nous ne voulons pas créer des millions de tels objets de chaîne. Nous pouvons utiliser Intern pour conserver une seule copie en mémoire. Pour une compréhension plus approfondie du stagiaire, veuillez vous référer à l'analyse approfondie de String # Intern.
Y a-t-il toujours des exceptions?
Savez-vous que le code suivant créera plusieurs objets de chaîne et enregistrera plusieurs références dans le pool constant de chaîne?
String test = "A" + "B" + "C";
La réponse est qu'un seul objet est créé et qu'une seule référence est enregistrée dans le pool constant. Nous utilisons la décompilation JAVAP et y faisons un œil.
17:02 $ Javap -C TesternedpoolGccCild à partir de "TesterNernedPoolgc.java" classe publique TesterNenedPoolgc étend java.lang.object {public TesInternedPoolgc (); CODE: 0: ALOAD_0 1: InvokeSpecial # 1; // Méthode java / lang / objet. "<Init>" :() v 4: returnPublic static void main (java.lang.string []) lève java.lang.exception; Code: 0: LDC # 2; // String ABC 2: Store_1 3: retourL'avez-vous vu? En fait, pendant la période de compilation, ces trois littéraux ont été synthétisés en un seul. Il s'agit en fait d'une optimisation qui évite de créer des objets de chaîne redondants et n'a pas de problèmes de couture de chaîne. Pour les coutures de chaîne, vous pouvez afficher les détails Java: couture de chaîne.
Ce qui précède est une compilation des informations sur les pools constants de chaînes en Java. Nous continuerons d'ajouter des informations pertinentes à l'avenir. Merci pour votre soutien à ce site!