OVH Cloud OVH Cloud

mémoire et strings

22 réponses
Avatar
Pif
Bonjour, quelqu'un connait il un endroit précis sur lequel on peut
trouver de l'info sur la gestion des strings en java, le persitence et
destruction via le GC...


j'ai besoin de manipuler beaucoup de chaines de caractères dont une
grande partie sont très temporaires... je veux pouvoir faciliter le
travail pour gagner en perfs !

merci !

10 réponses

1 2 3
Avatar
Pif
après avoir tout profilé, il semble que le problème soit notamment du à
la non destruction des strings qui proviennent des
rs.getString("nomduchamp");

malgré que tous passent par un rs.close();

une idée ?
Avatar
Hervé AGNOUX
Pif wrote:

ce n'est pas la qu'est le problème fait moi confiance.

La question, c'est comment lancer 1 000 000 de requetes en faisant en
sorte que la mémoire n'en prenne pas trop et que simplement les requetes
se détruisent au fur et a mesures sans occuper de mémoire ? Ce que
contient le termset n'a pas de rapport...


J'ai l'impression que tu as plutôt un problème de base de données que de
maps et de strings... Il me semble que cela se résout par un pool de
connexions ; essaie les commons de apache (DBCP :
http://jakarta.apache.org/commons/dbcp/, ou Dbutils :
http://jakarta.apache.org/commons/dbutils/), et recherche sur le canal java
à jdbc et pool :
http://www.java-channel.org/query.jsp?text=pool&hist=cids%3Dc_2031, par
exemple.


--
Hervé AGNOUX
http://www.diaam-informatique.com

Avatar
Pif
c'est quoi un pool exactement ?
Avatar
Pif
je croyais que c'était la map... mais après un coup de profiling, un des
problèmes vient en fait, non de la map, mais du getString() que je fais
sur le ResultSet, après 5 ou 6 méthodes d'après ce que m'indique le
profileur, il instancie un char[] qui n'est détruit qu'une fois sur
trois (pour 330000 objet, il y en a plus de 200 000 qui restent alive...).

Je fais pourtant bien un rs.close() a cet endroit.. je ne comprend pas !?


pour le pooling je connais pas trop, mais durant tout ca, a part un ptit
phpmyadmin, mon appli est la seule chose qui tourne, et elle fait un
seule connexion pour tout ca... donc je ne pense pas que ce soit un
élément de solution ?
Avatar
Kupee
Pif wrote:
après avoir tout profilé, il semble que le problème soit notamment du à
la non destruction des strings qui proviennent des
rs.getString("nomduchamp");

malgré que tous passent par un rs.close();

une idée ?


Euh que le driver Mysql stocke tout ce qui vient d'un ResultSet dans une
liste secrete statique, mais j'en doute. Tu as essayé de profiler en
supprimant tous les accès a ton termset voir si ca se garbage pas
correctement ?

Avatar
Pif
hum ... l'idée me paraissait indigne d'intéret à priori... je m'en
excuse platement...

en effet, il n'y a plus de soucis... étonnant si tu connais le code de
la seule fonction qui n'est pas le code que j'ai filé (celle qui
retourne un arraylist à partir des termes getString() effectués ).

La conclusion que j'en tire est donc :

le getString ne détruit pas la string pasqu'il reste une référence
attachée au termset, ce qui implique que quand on fait un substring, on
a pas une nouvelle instance en mémoire, mais on conserve une référence
vers la chaine d'où cela a été extrait !

vous le saviez vous ?

vous etes au courant de ces pratiques dans le JDK ?

merci bien en tout cas, cette tentative qui me paraissait désespérée
s'est vue particulièrement pertinente ! :))


Pif wrote:

après avoir tout profilé, il semble que le problème soit notamment du
à la non destruction des strings qui proviennent des
rs.getString("nomduchamp");

malgré que tous passent par un rs.close();

une idée ?



Euh que le driver Mysql stocke tout ce qui vient d'un ResultSet dans une
liste secrete statique, mais j'en doute. Tu as essayé de profiler en
supprimant tous les accès a ton termset voir si ca se garbage pas
correctement ?



Avatar
Kupee
Pif wrote:
hum ... l'idée me paraissait indigne d'intéret à priori... je m'en
excuse platement...

en effet, il n'y a plus de soucis... étonnant si tu connais le code de
la seule fonction qui n'est pas le code que j'ai filé (celle qui
retourne un arraylist à partir des termes getString() effectués ).

La conclusion que j'en tire est donc :

le getString ne détruit pas la string pasqu'il reste une référence
attachée au termset, ce qui implique que quand on fait un substring, on
a pas une nouvelle instance en mémoire, mais on conserve une référence
vers la chaine d'où cela a été extrait !

vous le saviez vous ?

vous etes au courant de ces pratiques dans le JDK ?

merci bien en tout cas, cette tentative qui me paraissait désespérée
s'est vue particulièrement pertinente ! :))


Tiens oui, le code de String.substring crée une nouvelle instance de
String, mais sur le même tableau de char[] que la première.
Ca a ses avantages et ses inconvénients : tu peux faire autant de
substring que tu veux sur une chaine, ca n'augmentera pas énormément la
mémoire utilisée. Par contre sur une chaine de 3 Mo tu fais un substring
pour récupérer que les 2 premiers caractères et tu jette la premiere
String, ta string de 2 caractères fera 3 Mo. amusant :D
Tu peux par contre faire new String(maString.substring(i,j)) et il fera
un System.ArrayCopy et donc utilisera plus le meme tableau de char[].
Ou alors peut etre utiliser intern() mais je sais pas dans quelles
conditions se vide le pool de Strings. Quelqu'un sait ca ?

Avatar
Pif
je l'avais déjà fait avant que tu le dise le new string() et maintenant
ca marche mieux !
je dépasse pas les 75 mo de ram ce qui est normal..
bon, je vous tiens au courant de la suite :)


enfin, je comprend pas qu'on soit pas tenu au courant d'évolutions
majeures de fonctions comme le substring !

ca peut foutre en l'air de tonnes de compatibilités descendantes ! plein
de vieux programmes (les miens les premiers peuvent se mettre à plus
tenir en mémoire avec ce genre de choses, ils auraient simplement pu
ajouter une seconde méthodes sans virer la premiere, je trouve ca
inadmissible à ce stade d'avancement de Java, sans compter que j'imagine
que toutes les JVM ne l'ont pas encore pris en compte...


Pif wrote:

hum ... l'idée me paraissait indigne d'intéret à priori... je m'en
excuse platement...

en effet, il n'y a plus de soucis... étonnant si tu connais le code
de la seule fonction qui n'est pas le code que j'ai filé (celle qui
retourne un arraylist à partir des termes getString() effectués ).

La conclusion que j'en tire est donc :

le getString ne détruit pas la string pasqu'il reste une référence
attachée au termset, ce qui implique que quand on fait un substring,
on a pas une nouvelle instance en mémoire, mais on conserve une
référence vers la chaine d'où cela a été extrait !

vous le saviez vous ?

vous etes au courant de ces pratiques dans le JDK ?

merci bien en tout cas, cette tentative qui me paraissait désespérée
s'est vue particulièrement pertinente ! :))



Tiens oui, le code de String.substring crée une nouvelle instance de
String, mais sur le même tableau de char[] que la première.
Ca a ses avantages et ses inconvénients : tu peux faire autant de
substring que tu veux sur une chaine, ca n'augmentera pas énormément la
mémoire utilisée. Par contre sur une chaine de 3 Mo tu fais un substring
pour récupérer que les 2 premiers caractères et tu jette la premiere
String, ta string de 2 caractères fera 3 Mo. amusant :D
Tu peux par contre faire new String(maString.substring(i,j)) et il fera
un System.ArrayCopy et donc utilisera plus le meme tableau de char[].
Ou alors peut etre utiliser intern() mais je sais pas dans quelles
conditions se vide le pool de Strings. Quelqu'un sait ca ?



Avatar
Lionel
Pif wrote:
enfin, je comprend pas qu'on soit pas tenu au courant d'évolutions
majeures de fonctions comme le substring !


pour info:
http://bugs.sun.com/bugdatabase/view_bug.do;:WuuT?bug_idF37640
Bug present depuis la 1.3, corrigé en 1.5 :)

Avatar
Kupee
Pif wrote:
je l'avais déjà fait avant que tu le dise le new string() et maintenant
ca marche mieux !
je dépasse pas les 75 mo de ram ce qui est normal..
bon, je vous tiens au courant de la suite :)


enfin, je comprend pas qu'on soit pas tenu au courant d'évolutions
majeures de fonctions comme le substring !

ca peut foutre en l'air de tonnes de compatibilités descendantes ! plein
de vieux programmes (les miens les premiers peuvent se mettre à plus
tenir en mémoire avec ce genre de choses, ils auraient simplement pu
ajouter une seconde méthodes sans virer la premiere, je trouve ca
inadmissible à ce stade d'avancement de Java, sans compter que j'imagine
que toutes les JVM ne l'ont pas encore pris en compte...


Comment ca, tu es sur qu'il y a eu une modification de ce coté là dans
les JVMs et que c'est pas comme ca depuis le début ?
Dans un sens ca se comprend leur truc, ca va beaucoup plus vite si tu
extrait plein de Strings temporaires. Le gros problème est que c'est pas
expliqué dans la doc ou alors j'ai pas vu ou.

1 2 3