GNT sans publicité, site mobile, fonctionnalitées exclusives...

Java JVM performances / garbage collector

Le
Lionel
Bonjour,

J'ai une appli web struts/hibernate qui tourne sur websphere5/oracle sous
winXP.
Elle a des besoins en mémoire assez gros pour certaines requetes: elles
remontent plusieurs milliers d'objets, (posés sur la HttpServletRequest).
Si je fais un appel à Runtime.freeMomory() avant et après, j'ai un delta de
-80Mo en moyenne (est-ce fiable comme indication ?).
Entre le lancement de la requete oracle, et le moment ou tous les objets ont
été chargés dans ma
servlet il se passe 5 à 6 secondes. (Utilisant hibernate, je ne vois pas
trop comment isoler le temps
de la requete sql)
Lors de l'affichage du tableau par la jsp, j'ai systématiquement un appel au
garbage collector identique à celui ci:

<AF[4]: Allocation Failure. need 770608 bytes, 68096 ms since last AF>
<AF[4]: managing allocation failure, action=1 (78473408/533723648)
(3145728/3145728)>
<GC(4): GC cycle started Wed Feb 09 12:03:47 2005
<GC(4): freed 337237824 bytes, 78% free (418856960/536869376), in 335 ms>
<GC(4): mark: 308 ms, sweep: 27 ms, compact: 0 ms>
<GC(4): refs: soft 0 (age >= 32), weak 0, final 54, phantom 0>
<AF[4]: completed in 336 ms>

Je suis en monoprocesseurr avec une JVM IBM 1.3.1, avec les
paramètres -verbose:gc -Xms512m -Xmx512m.
Je ne vois pas d'autres paramètres pour cette VM.

Lorsque mon appli est déployée sur le serveur (HP-UX 64bits biproc 750Mhz
RISC) les performances sont catastrophiques: tout est exactement 6 fois plus
lent que sur mon poste de dév pour la meme requete dans les meme conditions.
Le simple parcours de l'iterator est 2 fois plus lent sur le serveur
que sur mon poste (1.1 seconde contre 0.5sec)
Je n'ai pas accès au serveur pour savoir si c'est le garbage collector qui
ralentit autant l'application en occupant le cpu.
Le serveur utilise une Java HotSpot(TM) Server VM 1.3.1.09.

Comment expliquer un tel écart de perf alors que ce serveur est censé etre
nettement plus puissant sur le papier ?
Le GC et/ou la JVM peuvent elles etre responsables d'un tel écart ?

Note:
Ce serveur de test héberge une vingtaine d'applications, mais je n'ai aucune
possibilité de savoir ce qu'elle font ni qui les utilise en meme temps que
moi.
Je suppose que ce sont ces appli qui bouffent le cpu et ralentissent mon
appli, mais ne peux pas dépasser le stade de la supposition
je cherche donc à optimiser mon appli et son paramétrage au mieux avant de
remettre en cause le serveur.
Actuellement, je ne vois pas comment faire mieux sur mon poste de dév.

Merci pour vos conseils et expériences similaires
Lire les 20 réponses

Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 4
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Black Myst
Le #178790
Lionel wrote:
Bonjour,

J'ai une appli web struts/hibernate qui tourne sur websphere5/oracle sous
winXP.
Elle a des besoins en mémoire assez gros pour certaines requetes: elles
remontent plusieurs milliers d'objets, (posés sur la HttpServletRequest).
Si je fais un appel à Runtime.freeMomory() avant et après, j'ai un delta de
-80Mo en moyenne (est-ce fiable comme indication ?).
Entre le lancement de la requete oracle, et le moment ou tous les objets ont
été chargés dans ma
servlet il se passe 5 à 6 secondes. (Utilisant hibernate, je ne vois pas
trop comment isoler le temps
de la requete sql)
Lors de l'affichage du tableau par la jsp, j'ai systématiquement un appel au
garbage collector identique à celui ci:

<AF[4]: managing allocation failure, action=1 (78473408/533723648)
(3145728/3145728)>
<GC(4): GC cycle started Wed Feb 09 12:03:47 2005
<GC(4): freed 337237824 bytes, 78% free (418856960/536869376), in 335 ms>
<GC(4): mark: 308 ms, sweep: 27 ms, compact: 0 ms>
<GC(4): refs: soft 0 (age >= 32), weak 0, final 54, phantom 0>
<AF[4]: completed in 336 ms>

Je suis en monoprocesseurr avec une JVM IBM 1.3.1, avec les
paramètres -verbose:gc -Xms512m -Xmx512m.
Je ne vois pas d'autres paramètres pour cette VM.
Je connaissais pas l'option -verbose:gc, ca devrait pouvoir me servir


Lorsque mon appli est déployée sur le serveur (HP-UX 64bits biproc 750Mhz
RISC) les performances sont catastrophiques: tout est exactement 6 fois plus
lent que sur mon poste de dév pour la meme requete dans les meme conditions.
Le simple parcours de l'iterator est 2 fois plus lent sur le serveur
que sur mon poste (1.1 seconde contre 0.5sec)
Le truc classic pour faire chuter les perf, c'est le manque de mémoire

et le moment ou le systeme commence à swapper.
Plutot que le processeur, à ta place, je me rencarderais sur les dispo
en mémoire du serveur.

Je n'ai pas accès au serveur pour savoir si c'est le garbage collector qui
ralentit autant l'application en occupant le cpu.
Le serveur utilise une Java HotSpot(TM) Server VM 1.3.1.09.
Pourquoi ne pas utilisé la meme JVM en dev que sur le serveur ?

Et pourquoi ne pas installer une 1.5, elle est quand meme plus performante !


Comment expliquer un tel écart de perf alors que ce serveur est censé etre
nettement plus puissant sur le papier ?
Le GC et/ou la JVM peuvent elles etre responsables d'un tel écart ?

Note:
Ce serveur de test héberge une vingtaine d'applications, mais je n'ai aucune
possibilité de savoir ce qu'elle font ni qui les utilise en meme temps que
moi.
Je suppose que ce sont ces appli qui bouffent le cpu et ralentissent mon
appli, mais ne peux pas dépasser le stade de la supposition...
je cherche donc à optimiser mon appli et son paramétrage au mieux avant de
remettre en cause le serveur.
Il serait quand meme souhaitable que tu accède à cette machine pour

savoir ce qui passe...

Ne serai-ce que pour pouvoir suivre la consomation mémoire/proc pendant
l'execution de ta requete.

Actuellement, je ne vois pas comment faire mieux sur mon poste de dév.
C'est le momment de faire copain-copain avec les gens de la prod pour

voir ce qui ce passe sur ce serveur.

Merci pour vos conseils et expériences similaires...
Mon retoure d'expérience, c'est que quand un prog Java commence à swapé,

c'est souvent le début de la fin.

@+

Lionel
Le #178697
Black Myst wrote:
Le truc classic pour faire chuter les perf, c'est le manque de mémoire
et le moment ou le systeme commence à swapper.
Plutot que le processeur, à ta place, je me rencarderais sur les dispo
en mémoire du serveur.


Je pense également que le pb vient de là
10Go de ram sur le serveur.
256Mo en recette pour mon appli, 512Mo en prod.
Je ne connais pas le paramétrage des autres applis.

Pourquoi ne pas utilisé la meme JVM en dev que sur le serveur ?
Je n'ai pas de système 64bits chez moi :-)

Et pourquoi ne pas installer une 1.5, elle est quand meme plus
performante !
hum. Tu connais un websphere en VM 1.5 ?

En prod j'ai un WAS 5.0.2 en VM 1.3.
WAS 5.1 utilise une VM 1.4. Y a plus qu'à attendre la migration :)

Il serait quand meme souhaitable que tu accède à cette machine pour
savoir ce qui passe...
Ne rêvons pas :)


Ne serai-ce que pour pouvoir suivre la consomation mémoire/proc
pendant l'execution de ta requete.
Il y a 3 admin websphere pour ce serveur, c'est leur job, non ?


C'est le momment de faire copain-copain avec les gens de la prod pour
voir ce qui ce passe sur ce serveur.
Ils sont probablement protégés par 18 gardes du corps, enfermés dans une

cave, 200m sous terre. :)
Je ne peux meme pas leur téléphoner.

Mon retoure d'expérience, c'est que quand un prog Java commence à
swapé, c'est souvent le début de la fin.
C'est ce que je pense aussi.


g.zoritchak
Le #180106
"Lionel"
Bonjour,

J'ai une appli web struts/hibernate qui tourne sur websphere5/oracle sous
winXP.
Elle a des besoins en mémoire assez gros pour certaines requetes: elles
remontent plusieurs milliers d'objets, (posés sur la HttpServletRequest).
Si je fais un appel à Runtime.freeMomory() avant et après, j'ai un delta de
-80Mo en moyenne (est-ce fiable comme indication ?).
Entre le lancement de la requete oracle, et le moment ou tous les objets ont
été chargés dans ma
servlet il se passe 5 à 6 secondes. (Utilisant hibernate, je ne vois pas
trop comment isoler le temps
de la requete sql)


A mon avis tu as intérêt à mettre en place un workaround pour ces
requêtes spécifiques. 5-6s c'est énorme et cela plombe sans doute
complètement l'appli pour d'autres opérations. Tu as peu de chance de
monter en charge avec des requêtes problématiques comme ça. Utilise
des proc stock ou des requêtes plus générales pour traiter ces pb
particuliers.

Lionel
Le #180052
Gaetan Zoritchak wrote:
A mon avis tu as intérêt à mettre en place un workaround pour ces
requêtes spécifiques. 5-6s c'est énorme et cela plombe sans doute
complètement l'appli pour d'autres opérations. Tu as peu de chance de
monter en charge avec des requêtes problématiques comme ça. Utilise
des proc stock ou des requêtes plus générales pour traiter ces pb
particuliers.


il s'agit d'un select tout simple: le résultat d'un moteur de recherche dans
aucun filtre.
Ce n'est pas vraiment la requete sql qui pose problème (sinon cela serait
facile à résoudre), c'est la quantité d'informations qui sont remontées.
La collection remontée occupe 80Mo de mémoire.
Je milite pour que seuls une poignée d'utilisateurs aient accès au moteur de
recherche sans aucun filtre obligatoire, mais c'est pas gagné.
Actuellement une trentaine sur 110 y ont accès.
Et encore je peux faire pire, j'ai une table dans laquelle 500000 lignes
sont ajoutées chaque mois, avec laquelle une jointure peut être nécessaire
(selon les filtres sélectionnés).

Derek Sagan
Le #180051
Bonjour,

J'ai une appli web struts/hibernate qui tourne sur websphere5/oracle sous
winXP.
Elle a des besoins en mémoire assez gros pour certaines requetes: elles
remontent plusieurs milliers d'objets, (posés sur la HttpServletRequest).


Cela dit très respectueusement, c'est complètement irresponsable de
ramener autant d'objets, pour peu qu'ils soient bien gras c'est sûrement
là que sont tes 80 Mo.

Si je fais un appel à Runtime.freeMomory() avant et après, j'ai un delta de
-80Mo en moyenne (est-ce fiable comme indication ?).
Entre le lancement de la requete oracle, et le moment ou tous les objets ont
été chargés dans ma
servlet il se passe 5 à 6 secondes. (Utilisant hibernate, je ne vois pas
trop comment isoler le temps
de la requete sql)
Lors de l'affichage du tableau par la jsp, j'ai systématiquement un appel au
garbage collector identique à celui ci:

<AF[4]: managing allocation failure, action=1 (78473408/533723648)
(3145728/3145728)>
<GC(4): GC cycle started Wed Feb 09 12:03:47 2005
<GC(4): freed 337237824 bytes, 78% free (418856960/536869376), in 335 ms>
<GC(4): mark: 308 ms, sweep: 27 ms, compact: 0 ms>
<GC(4): refs: soft 0 (age >= 32), weak 0, final 54, phantom 0>
<AF[4]: completed in 336 ms>

Je suis en monoprocesseurr avec une JVM IBM 1.3.1, avec les
paramètres -verbose:gc -Xms512m -Xmx512m.
Je ne vois pas d'autres paramètres pour cette VM.

Lorsque mon appli est déployée sur le serveur (HP-UX 64bits biproc 750Mhz
RISC) les performances sont catastrophiques: tout est exactement 6 fois plus
lent que sur mon poste de dév pour la meme requete dans les meme conditions.
Le simple parcours de l'iterator est 2 fois plus lent sur le serveur
que sur mon poste (1.1 seconde contre 0.5sec)
Je n'ai pas accès au serveur pour savoir si c'est le garbage collector qui
ralentit autant l'application en occupant le cpu.
Le serveur utilise une Java HotSpot(TM) Server VM 1.3.1.09.

Comment expliquer un tel écart de perf alors que ce serveur est censé etre
nettement plus puissant sur le papier ?


Parce qu'un CPU de ton serveur est environe 2 fois moins rapide à
parcourir un iterateur que celui de ton poste de travail.
Sur le papier dont tu parles ton pa-risc ou ton itanium (je sais pas ce
que c'est ton hpux risc) torche un PC parce qu'il est testé avec une
application consommatrice d'I/O (ce en quoi le PC est mauvais et un
serveur unix bon) et surtout multithreadé donc capable d'utiliser
plusieurs CPU en même temps.
Pour faire un traitement con en mémoire avec un seul thread (par exemple
parcourir un énorme itérateur avec beaucoup trop d'objets) un CPU intel
torche n'importe quel cpu 64 bits riscs avec turbo-compresseur à
induction nucléaire.
A vue de nez je dirais que tu as un pentium entre 1.5GHz et 2GHz comme
poste de travail, ça doit être à peu près le ratio pour faire fois 2
avec ton 64 bits 750 MHz (mais bon, ne sachant si c'est un itanium ou un
pa, et n'en ayant un sous la main pour foutre un coup de chronomètre
dessus, c'est assez imprécis comme estimation).
Désolé d'égratigner un mythe, ce n'est pas pour sa puissance CPU pure
(un CPU à la fois) que ta boîte paye si cher HP. D'ailleurs pour jouer à
Half-Life 2 rien ne vaut un PC.

Le GC et/ou la JVM peuvent elles etre responsables d'un tel écart ?


La JVM peut y être un peu pour quelque chose aussi, et même l'OS si le
niveau de patch est débile par rapport aux patches JVM. Ou bien
quelqu'un d'autre utilise le serveur en même temps que toi et le sature.
Mais de loin le plus probable c'est ce que je dis ci-dessus.

Note:
Ce serveur de test héberge une vingtaine d'applications, mais je n'ai aucune
possibilité de savoir ce qu'elle font ni qui les utilise en meme temps que
moi.
Je suppose que ce sont ces appli qui bouffent le cpu et ralentissent mon
appli, mais ne peux pas dépasser le stade de la supposition...
je cherche donc à optimiser mon appli et son paramétrage au mieux avant de
remettre en cause le serveur.


C'est une très bonne démarche.

Actuellement, je ne vois pas comment faire mieux sur mon poste de dév.

Merci pour vos conseils et expériences similaires...


a+

Publicité
Suivre les réponses
Poster une réponse
Anonyme