Java Language Stockage de pool de chaînes et de tas


Exemple

Comme beaucoup d'objets Java, toutes les instances de String sont créées sur le tas, même les littéraux. Lorsque la machine JVM trouve un littéral String qui n'a pas de référence équivalente dans le tas, la machine virtuelle Java crée une instance String correspondante sur le segment de mémoire et stocke également une référence à l'instance String nouvellement créée dans le pool String. Toute autre référence au même littéral String est remplacée par l'instance String précédemment créée dans le tas.

Regardons l'exemple suivant:

class Strings
{
    public static void main (String[] args)
    {
        String a = "alpha";
        String b = "alpha";
        String c = new String("alpha");

        //All three strings are equivalent
        System.out.println(a.equals(b) && b.equals(c));

        //Although only a and b reference the same heap object
        System.out.println(a == b);
        System.out.println(a != c);
        System.out.println(b != c);
    }
}

Le résultat de ce qui précède est:

true
true
true
true

Diagramme du pool de tas et de chaînes Java Lorsque nous utilisons des guillemets doubles pour créer une chaîne, celle-ci recherche d'abord la chaîne avec la même valeur dans le pool de chaînes. Si elle est trouvée, elle renvoie simplement la référence, sinon elle crée une nouvelle chaîne dans le pool, puis renvoie la référence.

Cependant, en utilisant un nouvel opérateur, nous forçons la classe String à créer un nouvel objet String dans l’espace du tas. Nous pouvons utiliser la méthode intern () pour la placer dans le pool ou faire référence à un autre objet String d'un pool de chaînes ayant la même valeur.

Le pool de chaînes lui-même est également créé sur le tas.

Java SE 7

Avant Java 7, les littéraux de String étaient stockés dans le pool de constante d'exécution dans la zone de méthode de PermGen , qui avait une taille fixe.

Le pool de chaînes réside également dans PermGen .

Java SE 7

RFC: 6962931

Dans JDK 7, les chaînes internes ne sont plus allouées dans la génération permanente du segment de mémoire Java, mais sont plutôt allouées dans la partie principale du segment de mémoire Java (appelées générations jeunes et anciennes), avec les autres objets créés par l'application. . Cette modification se traduira par plus de données résidant dans le segment de mémoire principal Java et moins de données dans la génération permanente, ce qui peut nécessiter un ajustement de la taille des segments. La plupart des applications ne verront que des différences relativement faibles dans l'utilisation du tas en raison de ce changement, mais les applications plus volumineuses qui chargent de nombreuses classes ou qui utilisent String.intern() méthode String.intern() verront des différences plus significatives.