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
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

Poser une question


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.
Et pourquoi ne pas installer une 1.5, elle est quand meme plus performante !
savoir ce qui passe...
Ne serai-ce que pour pouvoir suivre la consomation mémoire/proc pendant
l'execution de ta requete.
voir ce qui ce passe sur ce serveur.
c'est souvent le début de la fin.
@+
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.
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 :)
cave, 200m sous terre. :)
Je ne peux meme pas leur téléphoner.
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).
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.
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.
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.
C'est une très bonne démarche.
a+