web-dev-qa-db-fra.com

Quand une chaîne sera-t-elle récupérée dans java

En Java, lorsqu'un objet n'a pas de référence en direct, il est éligible pour le garbage collection. Maintenant, dans le cas d'une chaîne, ce n'est pas le cas car la chaîne ira dans le pool de chaînes et la JVM gardera l'objet en vie pour une réutilisation. Cela signifie donc qu'une chaîne une fois créée ne sera "jamais" récupérée?

58
Victor

Maintenant, dans le cas d'une chaîne, ce n'est pas le cas car la chaîne ira dans le pool de chaînes et la JVM gardera l'objet en vie pour une réutilisation. Cela signifie donc qu'une chaîne une fois créée ne sera "jamais" récupérée?

Tout d'abord, ce sont uniquement chaîne littéraux (voir notes) qui obtiennent automatiquement interné/ajouté au pool de chaînes. String les objets créés par une application au moment de l'exécution ne sont pas internés ... sauf si votre application appelle explicitement String.intern().

Deuxièmement, en fait, les règles de récupération des objets dans le pool de chaînes sont les mêmes que pour les autres objets String: en effet, tous les objets. Ils seront récupérés s'ils deviennent inaccessibles.

En pratique, les objets String qui correspondent aux littéraux de chaîne généralement ne deviennent pas candidats à la récupération de place. En effet, il existe une référence implicite à l'objet String dans le code de chaque méthode utilisant le littéral. Cela signifie que String est accessible aussi longtemps que la méthode peut être exécutée.

Cependant, ce n'est pas toujours le cas. Si un littéral de chaîne a été défini dans une classe qui a été chargée dynamiquement (par exemple en utilisant Class.forName(...)), alors il est possible de faire en sorte que la classe soit déchargée . Si cela se produit, alors l'objet String correspondant au littéral peut être alors inaccessible, et peut finalement être GC'é.


Remarques:

  1. Un littéral de chaîne ( JLS 3.10.5 ) est une chaîne qui apparaît dans Java ; par exemple.

      "abc"            // string literal
      new String(...)  // not a string literal
    
  2. Une chaîne produite par l'évaluation de l'expression constante (au moment de la compilation) ( JLS 15.28 ) peut également être internée.

  3. À proprement parler, tous les littéraux String ne sont pas internés. Si un littéral String apparaît uniquement dans le code source en tant que sous-expression d'une expression constante, le littéral peut ne pas apparaître dans le fichier ".class" sous quelque forme que ce soit . Un tel littéral ne sera pas interné car il n'existera pas au moment de l'exécution.

69
Stephen C

Vous avez raison; les chaînes du pool de stagiaires ne seront jamais GC'd.

Cependant, la plupart des chaînes ne sont pas internées.
Chaîne littéraux sont internés et les chaînes passées à String.intern() sont internées, mais toutes les autres chaînes ne sont pas internées et peuvent être GC'd normalement.

8
SLaks