web-dev-qa-db-fra.com

Combien de mémoire une chaîne utilise-t-elle dans Java 8?

Dernièrement, j'ai beaucoup lu sur l'allocation de mémoire pour Strings et je ne trouve aucun détail si les choses se passent de la même façon avec Java 8.

Combien d’espace mémoire une chaîne comme "Alexandru Tanasescu" utiliserait-elle dans Java 8? J'utilise la version 64 bits.

27
Scartz

Java7 ou inférieur

Utilisation minimale de la mémoire en chaîne:

(bytes) = 8 * (int) ((((no chars) * 2) + 45) / 8)

Alors 

80 = 8 * (int) ((((19) * 2) + 45) / 8)

Comprendre l'utilisation de la mémoire en chaîne ( SOURCE )

Pour comprendre le calcul ci-dessus, nous devons commencer par examiner les champs d'un objet String. Une chaîne contient les éléments suivants:

  • un tableau de caractères - donc un objet séparé - contenant les caractères réels;
  • un entier décalé dans le tableau où la chaîne commence;
  • la longueur de la ficelle;
  • un autre int pour le calcul en cache du code de hachage.

Cela signifie que même si la chaîne ne contient aucun caractère, il faudra 4 octets pour la référence du tableau char, plus 3 * 4 = 12 octets pour les trois champs int, plus 8 octets d'en-tête d'objet. Cela donne 24 octets (ce qui est un multiple de 8, aucun octet de remplissage n’est donc nécessaire). 

Ensuite, le tableau de caractères (vide) nécessitera 12 octets supplémentaires (les tableaux ont 4 octets supplémentaires pour stocker leur longueur), plus dans ce cas 4 octets de remplissage pour amener la mémoire utilisée par l'objet de tableau de caractères à un multiple de 16. Donc, au total, une chaîne vide utilise 40 octets.

Si la variable String contient, par exemple, 19 caractères, l'objet String lui-même nécessite toujours 24 octets. Mais maintenant, le tableau de caractères nécessite 12 octets d’en-tête plus 19 * 2 = 38 octets pour les dix-sept caractères. Puisque 12 + 38 = 50 n'est pas un multiple de 8, nous devons également arrondir au multiple de 8 (56). Donc dans l’ensemble, notre String à 19 caractères utilisera jusqu’à 56 + 24 = 80 octets.


Java8.

Java 8 n'a plus les offset et length. Seulement hash et le CharArray.
@Thomas Jungblut

  • un tableau de caractères - donc un objet séparé - contenant les caractères réels;
  • un entier décalé dans le tableau où la chaîne commence;
  • la longueur de la ficelle;
  • un autre int pour le calcul en cache du code de hachage.

Ainsi, en Java8, la méthode de calcul de la mémoire pour les chaînes reste la même, mais vous devez soustraire 8 octets de moins en raison de la variable offset et length.

27
Jordi Castilla

Si vous regardez les sources Oracle Java 8, vous avez:

Un char value[] et un int hash. Une char correspond à 2 octets et une int à 4 octets.

Donc, la réponse ne serait-elle pas yourstring.length * 2 + 4?

Non, chaque objet avait des frais généraux. Un tableau stocke ses dimensions, par exemple. Et le tableau (un objet) et la chaîne engendreront de la mémoire supplémentaire du récupérateur de mémoire stockant des informations à leur sujet.

Il n’existe aucun moyen fiable de calculer cela, car, autant que je sache, JRE et JDK n’ont aucune obligation quant à la taille de la surcharge de l’objet. 

5
Ryan Goldstein

"Alexandru Tanasescu" utilise 104 octets. Voici comment obtenir la taille

    long m0 = Runtime.getRuntime().freeMemory();
    String s = new String("Alexandru Tanasescu");
    long m1 = Runtime.getRuntime().freeMemory();
    System.out.println(m0 - m1);

Remarque: exécutez-le avec l'option -XX: -UseTLAB

4
Evgeniy Dorofeev

Selon le PEC suivant: http://openjdk.Java.net/jeps/254

L'implémentation actuelle de la classe String stocke les caractères dans un tableau de caractères, utilisant deux octets (seize bits) pour chaque caractère.

Sous Java SE 9, cela pourrait changer.

Notez cependant qu'il s'agit d'un PEC et non d'un JSR (et qu'il mentionne l'implémentation), je comprends, qu'il s'agit d'implémentations spécifiques et non défini par le JLS.

0
Puce