Maison  >  Article  >  Java  >  Introduction graphique aux différences entre String, StringBuffer et StringBuilder et allocation de mémoire de pile en Java

Introduction graphique aux différences entre String, StringBuffer et StringBuilder et allocation de mémoire de pile en Java

黄舟
黄舟original
2017-03-04 09:33:061985parcourir

La classe String en Java est une classe très couramment utilisée, mais la moindre attention est accordée à ses détails, donc la plupart des entretiens se concentreront sur cette classe. Par exemple, String str = new String("hello"); ouvre plusieurs espaces mémoire, la différence entre String et StringBuffer, etc. Voici ma compréhension :

String est une classe modifiée par final et ne peut pas être héritée. StringBuffer est également une classe modifiée par final.

1. Division de la mémoire JVM

Il existe principalement 4 éléments de mémoire en Java. Ces espaces mémoire sont : l'espace mémoire de pile, l'espace mémoire de tas, la zone de données globale et la zone de code globale

1. Espace mémoire pile : enregistre tous les noms d'objets (l'adresse de l'espace mémoire tas référencé est enregistrée)

2. Espace mémoire tas : enregistre le contenu spécifique de chaque objet

3. Zone de données globales : enregistrer les attributs de données de type statique (données globales)

4. Zone de code global : enregistrer toutes les définitions de méthodes



Dans la JVM, la mémoire tas est l'espace mémoire qui stocke le contenu de l'instanciation de l'objet (les données du programme stockent le nom de l'objet et son contenu pointe vers l'adresse du tas correspondant).

On peut également dire que : tous les noms d'objets sont stockés dans la mémoire de pile et le contenu spécifique de l'objet est conservé dans la mémoire tas. Les données de type référence doivent utiliser le nouveau mot-clé pour ouvrir de l'espace dans la mémoire tas. .


2. Allocation de mémoire de Sring


String a une particularité : lors de la construction d'un objet String, vous pouvez utiliser une nouvelle construction ou "hello" pour le construire directement. Parmi les deux méthodes, il est recommandé d’utiliser la seconde.

1. String a = "hello";


2. String a= new String("hello");

L'explication est la suivante :


1 : Une référence d'objet est définie dans la mémoire pile, pointant vers l'adresse mémoire de la valeur "hello" dans la mémoire tas. Enfin un espace mémoire a été ouvert

2 : Une référence d'objet de a est redéfinie dans la mémoire de pile, pointant d'abord vers l'adresse mémoire de la mémoire tas avec la valeur "hello", puis pointant vers l'adresse de la mémoire tas avec la valeur de "hello " après neuf. Au final, deux espaces ont été ouverts. Le premier espace n'a aucune référence d'objet et sera récupéré par la JVM.

Le schéma est le suivant :

>

 
package andy.string.test;  
  
/**   
 * @author Zhang,Tianyou   
 * version:2014-11-25 下午4:15:14   
 *  
 *   
 */  
  
public class TestString {  
  
    public static void main(String[] args){  
        String a = "hello";  
        String b = "hello";  
        String c = new String("hello");  
        String d = new String();  
        d = "hello";  
        String e = c;  
          
        System.out.println("a==b ? " + (a== b));  
        System.out.println("a==c ? " + (c== b));  
        System.out.println("a==d ? " + (a== d));  
        System.out.println("a==e ? " + (a== e));  
        System.out.println("c==d ? " + (c== d));  
        System.out.println("c==e ? " + (c== e));  
    }  
}

  • Parmi eux seulement a==b==d, c=e.


Explication :
1. String ne veut pas attendre la mémoire du tas à chaque fois qu'elle est nouvelle, et d est alloué une nouvelle adresse après new et abandonne l'adresse après new pour pointer vers l'adresse mémoire correspondant à a, donc elles sont identiques.

2. L'espace mémoire du tas pointé par la méthode d'affectation directe "bonjour" est le même. String utilise une conception partagée en Java.Il forme un pool d'objets en Java.Si l'objet nouvellement instancié existe déjà dans le pool d'objets, il ne sera pas défini et utilisé directement à partir du pool d'objets. . Par conséquent, lorsque

est utilisé pour un contenu existant, l'objet pointera vers l'adresse spatiale de l'instance.

3. e pointe directement vers l'espace mémoire de C.

4. Par conséquent, lors de l'utilisation de String, il est recommandé d'utiliser l'affectation directe pour réduire l'espace mémoire et améliorer les performances.


3. La différence entre String, StringBuffer et StringBuilder

1. String, StringBuffer et StringBuilder sont tous modifiés par final et ne peuvent pas être hérités et réécrits. de.

2. Une fois String instancié, la taille du contenu de son espace mémoire ne peut pas être modifiée ; StringBuffer est une séquence de caractères variable thread-safe qui peut être modifiée dynamiquement dans la mémoire du tas après l'instanciation, donc la mémoire. la longueur et la taille sont variables ; une fois StringBuilder instancié, la taille et la longueur de la mémoire sont également variables, non

La différence est que StringBuilder n'est pas synchronisé avec les threads, son fonctionnement doit donc être plus efficace que StringBuffer.

Voici ce que certaines personnes penseront :

String str = "hello"

La valeur de str n'est pas A-t-elle changé aussi ?

En fait, le code ci-dessus a ouvert 3 espaces dans la mémoire, à savoir : "hello", "andy", "helloandy". Leur taille de mémoire tas est fixe, et enfin str pointe vers "helloandy". l'adresse du tas. Comme le montre la figure ci-dessous :

et StringBuffer n'ouvrira qu'un espace mémoire, vous pouvez utiliser APPEND pour ajouter du contenu d'opération tel que la suppression.

String Chaque fois qu'un objet est généré, cela aura un impact sur les performances du système. Surtout lorsqu'il y a trop d'objets non référencés dans la mémoire, le GC de la JVM commencera à fonctionner et la vitesse sera certainement assez élevée. lent. Mais si vous utilisez la classe StringBuffer/StringBuilder, le résultat sera différent à chaque fois, le résultat sera une opération sur l'objet StringBuffer/StringBuilder lui-même, au lieu de générer un nouvel objet puis de changer la référence de l'objet.


Par conséquent, lors de l'attribution d'une chaîne dans une boucle, il est préférable d'utiliser StringBuffer (thread-safe) ou StringBuilder, qui peuvent économiser de la mémoire et améliorer les performances.

Ce qui précède est la différence entre la différence entre String, StringBuffer et StringBuilder en Java et le contenu introduit par l'allocation de mémoire de pile. Pour plus de contenu connexe, veuillez suivre PHP chinois (www.php.cn). !

Déclaration:
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