Maison Java JavaBase Explication graphique et textuelle détaillée du pool de constantes Java

Explication graphique et textuelle détaillée du pool de constantes Java

Nov 30, 2019 pm 04:36 PM
java

Explication graphique et textuelle détaillée du pool de constantes Java

Le pool constant Java est un sujet récurrent et un favori des intervieweurs. Il y a une variété de questions que Xiaocai a déjà entendu parler du pool constant.

Recommandation : Tutoriel vidéo Java

Distribution de la mémoire virtuelle jvm :

Explication graphique et textuelle détaillée du pool de constantes Java

Le compteur du programme est l'endroit où se trouve le jvm exécute le programme. Le pipeline stocke certaines instructions de saut. C'est trop avancé pour que Xiao Cai puisse le comprendre.

La pile de méthodes locales est la pile utilisée par la jvm pour appeler les méthodes du système d'exploitation.

La pile de machine virtuelle est la pile utilisée par jvm pour exécuter du code java.

La zone de méthode stocke certaines constantes, variables statiques, informations de classe, etc., qui peuvent être comprises comme l'emplacement de stockage des fichiers de classe en mémoire.

Le tas de la machine virtuelle est le tas utilisé par la jvm pour exécuter du code java.

Le pool de constantes en Java est en fait divisé en deux formes : le pool de constantes statiques et le pool de constantes d'exécution.

Le pool de constantes dites statiques est le pool de constantes dans le fichier *.class. Le pool de constantes dans le fichier de classe contient non seulement des littéraux de chaîne (nombre), mais contient également des informations de classe et de méthode, occupant absolument. aucune partie du fichier de classe.

Quant au pool de constantes d'exécution, une fois que la machine virtuelle jvm a terminé l'opération de chargement de classe, elle charge le pool de constantes dans le fichier de classe dans la mémoire et l'enregistre dans la zone de méthode. Nous l'appelons souvent la constante. pool , fait référence au pool de constantes d'exécution dans la zone de méthode.

Ensuite, nous citerons quelques exemples de pools constants populaires sur Internet, puis nous les utiliserons pour expliquer.

String s1 = "Hello";
String s2 = "Hello";
String s3 = "Hel" + "lo";
String s4 = "Hel" + new String("lo");
String s5 = new String("Hello");
String s6 = s5.intern();
String s7 = "H";
String s8 = "ello";
String s9 = s7 + s8;
          
System.out.println(s1 == s2);  // true
System.out.println(s1 == s3);  // true
System.out.println(s1 == s4);  // false
System.out.println(s1 == s9);  // false
System.out.println(s4 == s5);  // false
System.out.println(s1 == s6);  // true
Copier après la connexion

Tout d'abord, en Java, l'opérateur == est utilisé directement pour comparer les adresses de référence de deux chaînes, pas le contenu. Veuillez utiliser String.equals() pour comparer le contenu.

s1 == s2 est très facile à comprendre. Lors de l'attribution de valeurs à s1 et s2, les deux utilisent des chaînes littérales. Pour parler franchement, cela signifie écrire directement la chaîne à mort lors de la compilation. de littéral sera directement placé dans le pool de constantes du fichier de classe pour réaliser la réutilisation. Après avoir chargé le pool de constantes d'exécution, s1 et s2 pointent vers la même adresse mémoire, ils sont donc égaux.

s1 == s3 a un piège. Bien que s3 soit une chaîne épissée dynamiquement, toutes les parties impliquées dans l'épissage sont des littéraux connus. Lors de la compilation, cet épissage sera optimisé, le compilateur l'épellera directement. pour vous, donc String s3 = "Hel" + "lo"; est optimisé en String s3 = "Hello"; dans le fichier de classe, donc s1 == s3 est établi.

Bien sûr, s1 == s4 n'est pas égal. Bien que s4 soit également épissé, la nouvelle partie String("lo") n'est pas un littéral connu et est une partie imprévisible. le résultat ne peut pas être déterminé avant l'exécution. Combiné avec le théorème d'invariance des chaînes, qui sait où s4 est alloué, donc l'adresse doit être différente. Un diagramme simple est fourni pour clarifier l'idée :

Explication graphique et textuelle détaillée du pool de constantes Javas1 == s9 n'est pas égal, et la raison est similaire, bien que s7 et s8 utilisent des littéraux de chaîne lors de l'attribution de valeurs, lorsqu'ils sont épissés. dans s9, En tant que deux variables, s7 et s8 sont imprévisibles. Après tout, le compilateur est un compilateur et ne peut pas être utilisé comme interpréteur, donc aucune optimisation n'est effectuée lors de l'exécution, la nouvelle chaîne fusionnée par s7 et s8 sera. à l'adresse dans le tas. Je ne suis pas sûr, cela ne peut pas être la même que l'adresse s1 dans le pool constant de la zone de méthode.

Explication graphique et textuelle détaillée du pool de constantes Java

s4 == s5 n'a plus besoin d'explication, absolument pas égal, les deux sont dans le tas, mais ont des adresses différentes.

s1 == s6 Ces deux égalités sont entièrement dues à la méthode interne s5 est dans le tas et le contenu est Hello. La méthode interne tentera d'ajouter la chaîne Hello au pool de constantes et de la renvoyer. le pool de constantes. Comme il existe déjà une chaîne Hello dans le pool de constantes, la méthode interne renvoie directement l'adresse ; et s1 pointe déjà vers le pool de constantes lors de la compilation, donc s1 et s6 pointent vers la même adresse et sont égaux.

À ce stade, nous pouvons tirer trois conclusions très importantes :

Nous devons prêter attention au comportement au moment de la compilation afin de mieux comprendre le pool constant.

Les constantes du pool de constantes d'exécution proviennent essentiellement du pool de constantes de chaque fichier de classe.

Lorsque le programme est en cours d'exécution, le jvm n'ajoutera pas automatiquement de constantes au pool de constantes, sauf si vous ajoutez manuellement des constantes au pool de constantes (par exemple en appelant la méthode interne).

Ce qui précède concerne uniquement les pools de constantes de chaîne. En fait, il existe également des pools de constantes entières, des pools de constantes à virgule flottante, etc., mais ils sont tous similaires, sauf que vous ne pouvez pas ajouter manuellement de constantes à la constante de type numérique. pool. Les constantes du pool de constantes ont été déterminées au démarrage du programme. Par exemple, la plage de constantes dans le pool de constantes entières est : -128~127. Seuls les nombres de cette plage peuvent être utilisés dans le pool de constantes.

Pratique

Après avoir dit tant de théorie, abordons le véritable bassin constant.

Comme mentionné précédemment, il existe un pool de constantes statiques dans le fichier de classe. Ce pool de constantes est généré par le compilateur et est utilisé pour stocker les littéraux dans les fichiers source Java (cet article se concentre uniquement sur les littéraux). Il y a le code java suivant :

 String s = "hi";
Copier après la connexion

为了方便起见,就这么简单,没错!将代码编译成class文件后,用winhex打开二进制格式的class文件。如图:

Explication graphique et textuelle détaillée du pool de constantes Java

简单讲解一下class文件的结构,开头的4个字节是class文件魔数,用来标识这是一个class文件,说白话点就是文件头,既:CA FE BA BE。

紧接着4个字节是java的版本号,这里的版本号是34,因为笔者是用jdk8编译的,版本号的高低和jdk版本的高低相对应,高版本可以兼容低版本,但低版本无法执行高版本。所以,如果哪天读者想知道别人的class文件是用什么jdk版本编译的,就可以看这4个字节。

接下来就是常量池入口,入口处用2个字节标识常量池常量数量,本例中数值为00 1A,翻译成十进制是26,也就是有25个常量,其中第0个常量是特殊值,所以只有25个常量。

常量池中存放了各种类型的常量,他们都有自己的类型,并且都有自己的存储规范,本文只关注字符串常量,字符串常量以01开头(1个字节),接着用2个字节记录字符串长度,然后就是字符串实际内容。本例中为:01 00 02 68 69。

接下来再说说运行时常量池,由于运行时常量池在方法区中,我们可以通过jvm参数:-XX:PermSize、-XX:MaxPermSize来设置方法区大小,从而间接限制常量池大小。

假设jvm启动参数为:-XX:PermSize=2M -XX:MaxPermSize=2M,然后运行如下代码:

//保持引用,防止自动垃圾回收
List<String> list = new ArrayList<String>();
        
int i = 0;
        
while(true){
    //通过intern方法向常量池中手动添加常量
    list.add(String.valueOf(i++).intern());
}
Copier après la connexion

程序立刻会抛出:Exception in thread "main" java.lang.outOfMemoryError: PermGen space异常。PermGen space正是方法区,足以说明常量池在方法区中。

在jdk8中,移除了方法区,转而用Metaspace区域替代,所以我们需要使用新的jvm参数:-XX:MaxMetaspaceSize=2M,依然运行如上代码,抛出:java.lang.OutOfMemoryError: Metaspace异常。同理说明运行时常量池是划分在Metaspace区域中。具体关于Metaspace区域的知识,请读者自行搜索。

更多java知识请关注java基础教程栏目。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Nombre parfait en Java Nombre parfait en Java Aug 30, 2024 pm 04:28 PM

Guide du nombre parfait en Java. Nous discutons ici de la définition, comment vérifier le nombre parfait en Java ?, des exemples d'implémentation de code.

Weka en Java Weka en Java Aug 30, 2024 pm 04:28 PM

Guide de Weka en Java. Nous discutons ici de l'introduction, de la façon d'utiliser Weka Java, du type de plate-forme et des avantages avec des exemples.

Numéro de Smith en Java Numéro de Smith en Java Aug 30, 2024 pm 04:28 PM

Guide du nombre de Smith en Java. Nous discutons ici de la définition, comment vérifier le numéro Smith en Java ? exemple avec implémentation de code.

Questions d'entretien chez Java Spring Questions d'entretien chez Java Spring Aug 30, 2024 pm 04:29 PM

Dans cet article, nous avons conservé les questions d'entretien Java Spring les plus posées avec leurs réponses détaillées. Pour que vous puissiez réussir l'interview.

Break or Return of Java 8 Stream Forach? Break or Return of Java 8 Stream Forach? Feb 07, 2025 pm 12:09 PM

Java 8 présente l'API Stream, fournissant un moyen puissant et expressif de traiter les collections de données. Cependant, une question courante lors de l'utilisation du flux est: comment se casser ou revenir d'une opération FOREAK? Les boucles traditionnelles permettent une interruption ou un retour précoce, mais la méthode Foreach de Stream ne prend pas directement en charge cette méthode. Cet article expliquera les raisons et explorera des méthodes alternatives pour la mise en œuvre de terminaison prématurée dans les systèmes de traitement de flux. Lire plus approfondie: Améliorations de l'API Java Stream Comprendre le flux Forach La méthode foreach est une opération terminale qui effectue une opération sur chaque élément du flux. Son intention de conception est

Horodatage à ce jour en Java Horodatage à ce jour en Java Aug 30, 2024 pm 04:28 PM

Guide de TimeStamp to Date en Java. Ici, nous discutons également de l'introduction et de la façon de convertir l'horodatage en date en Java avec des exemples.

Programme Java pour trouver le volume de la capsule Programme Java pour trouver le volume de la capsule Feb 07, 2025 am 11:37 AM

Les capsules sont des figures géométriques tridimensionnelles, composées d'un cylindre et d'un hémisphère aux deux extrémités. Le volume de la capsule peut être calculé en ajoutant le volume du cylindre et le volume de l'hémisphère aux deux extrémités. Ce tutoriel discutera de la façon de calculer le volume d'une capsule donnée en Java en utilisant différentes méthodes. Formule de volume de capsule La formule du volume de la capsule est la suivante: Volume de capsule = volume cylindrique volume de deux hémisphères volume dans, R: Le rayon de l'hémisphère. H: La hauteur du cylindre (à l'exclusion de l'hémisphère). Exemple 1 entrer Rayon = 5 unités Hauteur = 10 unités Sortir Volume = 1570,8 unités cubes expliquer Calculer le volume à l'aide de la formule: Volume = π × r2 × h (4

Créer l'avenir : programmation Java pour les débutants absolus Créer l'avenir : programmation Java pour les débutants absolus Oct 13, 2024 pm 01:32 PM

Java est un langage de programmation populaire qui peut être appris aussi bien par les développeurs débutants que par les développeurs expérimentés. Ce didacticiel commence par les concepts de base et progresse vers des sujets avancés. Après avoir installé le kit de développement Java, vous pouvez vous entraîner à la programmation en créant un simple programme « Hello, World ! ». Une fois que vous avez compris le code, utilisez l'invite de commande pour compiler et exécuter le programme, et « Hello, World ! » s'affichera sur la console. L'apprentissage de Java commence votre parcours de programmation et, à mesure que votre maîtrise s'approfondit, vous pouvez créer des applications plus complexes.

See all articles