Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Reset d'un StringBuffer

7 réponses
Avatar
Kupee
Salut j'aimerai resetter un StringBuffer, j'utilise donc la méthode
setLength(0), or cette méthode ne peut réduire la longueur d'un
StringBuffer que si celui-ci est "shared" c'est a dire que son char[]
est partagé avec une String, ce qui arrive quand on fait un toString()
Si il n'est pas "shared" setValue(0) ne fait rien. Comment faire ?
Sans réinstantier un autre StringBuffer bien sur (:

7 réponses

Avatar
Kupee
Christophe M. wrote:

Ha bon, y a des partages d'infos entre classes ?
Et en essayant le sb.delete(0,sb.length()) ?


Malheureusement le delete ne réduit pas la taille du char[]
donc on ne récupère pas de mémoire. En réalité plus je regarde
setLength(int) plus je me dis qu'il y a un petit bug dans
l'implémentation de l'API ... Mais en meme temps il y a peut
etre une raison que je n'ai pas trouvé ...

Avatar
Kupee
Arnaud Roger wrote:
Throw the used StringBuffers away!

http://www.javaspecialists.co.za/archive/Issue068.html

Ceci explique pourquoi ca ne sert plus a rien de réutiliser un StringBuffer.
Alors au lieu de faire un setLength(0), il est conseillé de le reconstruire.


Ah ben ils arrivent a la meme conclusion que je redoutais, merci pour
l'article intéréssant

Avatar
Kupee
Christophe M. wrote:
En lisant l'article donné par Arnaud, tu comprendras mieux le "bug" :-)

Résumé : depuis la version 1.4.1, le setLength() à changé
d'implémentation, du coup ça marche plus comme avant :-(

Mais si c'est pour gagner de la mémoire (tu n'avais pas précisé le but
de ta manoeuvre) la création d'un nouveau StringBuffer va justement
"annuler" la référence de l'ancien et le donner à disposition du
"garbage collector".

Mais si ton tableau de char[] est bien partagé avec un autre String, il
va de toute façon rien déallouer comme mémoire, et donc tu n'y gagneras
pas plus...


Oui et non en fait, car le StringBuffer est shared uniquement tant qu'on
ne le modifie pas, dès qu'on le modifie une copie du tableau de char
est faite afin de ne pas modifier la String et que celle ci reste
immuable. Le setLength() aurait donc pu me faire gagner de la mémoire
car le StringBuffer aurait récupéré un tableau de char de taille
raisonnable au lieu d'etre dupliqué (ils ont un arrayCopy lorsqu'on
modifie un StringBuffer qui est shared avec une String

Avatar
Kupee
Christophe M. wrote:
J'ai pas du tout comprendre...

Le tableau de char[] est partagé, donc en mémoire. Si tu le modifie, il
copy le tableau pour que le String soit tjrs valide, d'ou une perte de
mémoire effectivement vu qu'il copie le gros tableau avant de le
modifier...

Par contre, si tu re-crée ton StringBuffer, il va justement re-créer un
char[16] donc un plus petit tableau, donc tu y gagnes.

c'est ça ?

Donc en fait, re-créer un nouveau StringBuffer est plus "éfficace" que
de faire un setLength() comme tu le croyais au début, non ?


Oui voilà, en fait si le StringBuffer est shared il va bien recréer son
char[16] mais s'il ne l'est pas il va le garder tel-quel et ne faire que
changer son champ count

Avatar
Christophe M.
En lisant l'article donné par Arnaud, tu comprendras mieux le "bug" :-)

Résumé : depuis la version 1.4.1, le setLength() à changé
d'implémentation, du coup ça marche plus comme avant :-(

Mais si c'est pour gagner de la mémoire (tu n'avais pas précisé le but
de ta manoeuvre) la création d'un nouveau StringBuffer va justement
"annuler" la référence de l'ancien et le donner à disposition du
"garbage collector".

Mais si ton tableau de char[] est bien partagé avec un autre String, il
va de toute façon rien déallouer comme mémoire, et donc tu n'y gagneras
pas plus...


Kupee wrote:

Christophe M. wrote:

Ha bon, y a des partages d'infos entre classes ?
Et en essayant le sb.delete(0,sb.length()) ?



Malheureusement le delete ne réduit pas la taille du char[]
donc on ne récupère pas de mémoire. En réalité plus je regarde
setLength(int) plus je me dis qu'il y a un petit bug dans
l'implémentation de l'API ... Mais en meme temps il y a peut
etre une raison que je n'ai pas trouvé ...




Avatar
Didier Bolf
est ce que tu as jeté un oeil au code de StringBuffer ?

"Kupee" wrote in message
news:3f2038c7$0$28678$
Salut j'aimerai resetter un StringBuffer, j'utilise donc la méthode
setLength(0), or cette méthode ne peut réduire la longueur d'un
StringBuffer que si celui-ci est "shared" c'est a dire que son char[]
est partagé avec une String, ce qui arrive quand on fait un toString()
Si il n'est pas "shared" setValue(0) ne fait rien. Comment faire ?
Sans réinstantier un autre StringBuffer bien sur (:



Avatar
Kupee
Didier Bolf wrote:
est ce que tu as jeté un oeil au code de StringBuffer ?


Oui, et la méthode setLength(0) ne réinstantie un char[16] que
si la méthode toString() a été appelée, donc on ne récupère pas de
mémoire puisque l'ancien char[] se retrouve dans la String.
Si on a pas appelé toString() on ne fait que remettre le champ
déterminant la taille a pas beaucoup sans réinitialiser le char[]