47 votes

String vs char[]

J'ai quelques diapositives à partir d'IBM nommé : "à Partir du Code Java pour Java Heap: la Compréhension de l'Utilisation de la Mémoire de Votre Application", qui dit que, lorsque nous utilisons String au lieu de char[], il est

Au Maximum les frais généraux serait de 24:1 pour un seul personnage!

mais je ne suis pas capable de comprendre ce que les frais généraux est référencé ici. Quelqu'un peut-il aider s'il vous plaît?

Source :

enter image description here

38voto

Andrey Chaschev Points 6372

Ce chiffre se rapporte à JDK 6 32 bits.

JDK 6

En pré-Java-7 le monde des chaînes qui ont été mis en œuvre comme un pointeur vers une région d'un char[] tableau:

// "8 (4)" reads "8 bytes for x64, 4 bytes for x32"

class String{      //8 (4) house keeping + 8 (4) class pointer
    char[] buf;    //12 (8) bytes + 2 bytes per char -> 24 (16) aligned
    int offset;    //4 bytes                     -> three int
    int length;    //4 bytes                     -> fields align to
    int hash;      //4 bytes                     -> 16 (12) bytes
}

Donc, j'ai compté:

36 bytes per new String("a") for JDK 6 x32  <-- the overhead from the article
56 bytes per new String("a") for JDK 6 x64.


JDK 7

Juste pour comparer, dans le JDK 7+ String est une classe qui contient un char[] tampon et un hash domaine seulement.

class String{      //8 (4) + 8 (4) bytes             -> 16 (8)  aligned
    char[] buf;    //12 (8) bytes + 2 bytes per char -> 24 (16) aligned
    int hash;      //4 bytes                         -> 8  (4)  aligned
}

Donc, c'est:

28 bytes per String for JDK 7 x32 
48 bytes per String for JDK 7 x64.

Mise à JOUR

Pour 3.75:1 ratio de voir @Andrey l'explication ci-dessous. Cette proportion tombe à 1 que la longueur de la chaîne augmente.

Liens utiles:

9voto

Shoaib Chikate Points 2772

Dans la JVM, une variable de caractère est stocké dans un seul de 16 bits de l'allocation de mémoire et des changements à cette variable Java écraser le même emplacement mémoire.Cela rend la création ou la mise à jour de variables de caractères très rapide et de la mémoire à bas prix, mais augmente la JVM de frais généraux par rapport à l'allocation statique utilisé dans les Chaînes.

La JVM magasins Java Chaînes de caractères dans une variable de la taille de l'espace mémoire (essentiellement, un tableau), ce qui est exactement la même taille (plus 1, pour la fin de chaîne de caractères) de la chaîne lorsque la Chaîne de création de l'objet ou de la première d'attribuer une valeur. Ainsi, un objet de valeur initiale "à l'AIDE!" serait alloué 96 bits de stockage ( 6 caractères, chacun des 16-bits). Cette valeur est considérée comme immuable, permettant à la JVM de l'inclure des références à cette variable, prise statique de la chaîne des affectations très rapide, et très compact et très efficace de la JVM point de vue.

Référence

3voto

Andrey Points 2962

Je vais essayer d'expliquer le nombre référencé dans la source de l'article.

L'article décrit les métadonnées de l'objet généralement composé de: classe, des drapeaux et de la serrure.

La classe et de verrouillage sont stockées dans l'objet de l'en-tête et de prendre de 8 octets sur 32 bits VM. Je n'ai pas trouvé que toute l'information à propos de la JVM des implémentations qui a des drapeaux de l'info dans l'en-tête objet. C'est peut-être alors que c'est stockée quelque part à l'extérieur (par exemple par le garbage collector pour compter les références à l'objet, etc.).

Supposons donc que l'article parle de quelques x32 AbstractJVM qui utilise 12 octets de mémoire pour stocker des méta-informations sur l'objet.

Alors pour char[] nous avons:

  • 12 octets de méta-informations (8 octets sur x32 JDK 6, 16 octets sur x64 JDK)
  • 4 octets pour la taille du tableau
  • 2 octets pour chaque caractère stocké
  • 2 octets de l'alignement si les caractères nombre est impair (x64 JDK: 2 * (4 - (length + 2) % 4))

Pour java.lang.String nous avons:

  • 12 octets de méta-informations (8 octets sur x32 JDK6, 16 octets sur x64 JDK6)
  • 16 octets pour les champs de type Chaîne (il en est ainsi pour JDK6, de 8 octets pour JDK7)
  • la mémoire nécessaire pour stocker char[] comme décrit ci-dessus

Donc, nous allons compter la quantité de mémoire nécessaire pour stocker "MyString" comme String objet:

12 + 16 + (12 + 4 + 2 * "MyString".length + 2 * ("MyString".length % 2)) = 60 bytes.

De l'autre côté, nous savons que pour stocker uniquement les données (sans information sur le type de données, la longueur ou quoi que ce soit d'autre) nous avons besoin de:

2 * "MyString".length = 16 bytes

La surcharge est - 60 / 16 = 3.75

De même pour le caractère unique de la matrice de nous obtenir le maximum de frais généraux':

12 + 16 + (12 + 4 + 2 * "a".length + 2 * ("a".length % 2)) = 48 bytes
2 * "a".length = 2 bytes
48 / 2 = 24

La suite de l'article des auteurs de la logique en fin de compte le montant maximal des frais généraux de la valeur de l'infini est réalisée lorsque l'on stocker une chaîne vide :).

1voto

chiru Points 189

J'avais lu de vieux stackoverflow réponse n'est pas en mesure de l'obtenir. Dans d'Oracle JDK une Chaîne a quatre par exemple au niveau des champs:

A character array
An integral offset
An integral character count
An integral hash value

Cela signifie que chaque Chaîne introduit un objet supplémentaire de référence (la Chaîne elle-même), et les trois entiers en plus du tableau de caractères elle-même. (Le décalage et le nombre de caractères sont là pour permettre le partage de la matrice de caractères entre les instances de Chaîne produite par la Chaîne#substring (), un choix de conception que certains autres bibliothèque Java réalisateurs ont préféré.) Au-delà de l'espace de stockage supplémentaire coût, il y a aussi un plus au niveau de l'accès indirection, pour ne pas mentionner la vérification des limites avec la Chaîne des gardes de son tableau de caractères.

Si vous pouvez vous en sortir avec l'allocation et de consommer le minimum pour tableau de caractères, il y a de l'espace pour être sauvé. Ce n'est certainement pas idiomatiques de le faire en Java; judicieux commentaires serait justifiée pour justifier les choix, de préférence avec mention de la preuve d'avoir dressé le portrait de la différence.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X