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

Ralentissements importants sur une une appli java/swing

15 réponses
Avatar
Glop
Bonjour

J'ai une appli écrite en java/swing et utilisant des tas de librairies, avec
un code pas parfaitement optimisé. Tout cela la fait déjà ramer pas mal mais
jusqu'ici c'était tenable.

L'IHM permet d'ouvrir une série de boîtes de dialogue qui sont toutes
construites suivant un schéma identique. A leur "tête", une classe mère java
permettant de créer dynamiquement la boîte qui m'intéresse avec son contenu
(champs de saisie, combos...). Chaque boîte de dialogue la dérive ensuite
pour son propre compte.

A la création, certaines boîtes seulement bouffent une mémoire pas possible
(jusqu'à 80Mo la première fois) alors que la grande majorité des autres
gratte 1Mo à tout casser. Cette mémoire n'est pas restituée à la fermeture
et au coup d'après environ 20 à 30Mo de plus sont utilisés et ainsi de
suite.

Les recherches ont mis en évidence que l'exécution de la méthode pack() à
elle seule prenait presque 30s. Cette méthode se trouve dans la classe mère
de toutes les fenêtres. Il est impossible de s'en passer.

Qui aurait une explication sur le fait que seules certaines fenêtres (avec
beaucoup de contenu mais il y en a d'autres) utilisent autant de mémoire à
cause de cette méthode (ou autre ?) ?

Sachant qu'on utilise java 1.5.08, que le problème a été résolu en mettant
des options de réservation mémoire dans la commande java sur PC mais que
l'application devant tourner aussi sur SunOS, cette optimisation ne
fonctionne pas . En effet la mémoire totale utilisée par l'appli (Résultat
donné par la commande 'top') plafonne à une valeur insuffisante alors qu'il
en reste pourtant pas mal de disponible, c'est peut-être du au système
comment savoir...

Autres tentatives effectuées: remplacer l'appel à pack(), utiliser le gc(),
en vain. Je n'ai pas non plus d'outil de mesures à disposition.

Merci pour vos réponses.

5 réponses

1 2
Avatar
Glop
"Hervé AGNOUX" a écrit dans le
message de news: 45d99643$0$3873$
Glop wrote:


Le chargement en tant que tel peut-être pas (lecture d'un petit fichier
xml) mais sa redistribution dans l'arbre DOM associé sans doute.



Si c'est un petit fichier XML (inférieur à 100 Ko), je doute que ce soit
ça.
Peux-tu faire un essai avec un fichier complètement vide (ou au minimum
? )


Je suis même partie de zéro mais ça ne change rien.

- ne pas appeler pack !


Dans ce cas on obtient un petit rectangle qu'il faut redimensionner à la
main pour voir apparaître tous les champs. Ce n'est pas envisageable.



Oui mais dans ce cas, est-ce que le temps d'affichage est le même ? Lors
du
redimenssionnement, est-ce que le réaffichage prend beaucoup de temps ?


Non là c'est immédiat.



Avatar
Glop
"Francis JUGE-BOIRARD" a écrit dans le message de news:
erc8rl$1ecp$
Je pense que vous n'êtes pas sur la bonne piste, il y a visiblement une
fuite de mémoire mais je doute qu'elle soit due à Swing. Il est plus
probable que l'appel de pack rame par ce qu'un autre process (chargement
de données ???) prend énormément de temps.


Rien que le lancement de l'HM prend un certain temps et pourtant aucun
fichier n'est chargé. Après, effectivement le contenu du fichier XML est
"déversé dans un arbre DOM et ça n'est pas immédiat. Mais ces boîtes de
dialogues sont destinées chacune à mettre à jour une partie des informations
de cet arbre. Pourquoi cela serait-il rapide pour certaines parties et pas
pour d'autres...

Mon expérience java est relativement neuve mais quand même, c'est un langage
plutôt blindé par rapport à C++. Comment peut-il y avoir des fuites
mémoires, même si c'est la faute du programmeur ? En plus même si la
conception s'est faite en même temps que la réalisation l'appli est loin
d'avoir été codée par des manchots.

JProfiler serait sympa mais je pense qu'en posant des traces directement
dans le code, il doit être possible de cerner plus précisément le
problème.


On l'a fait mais pas eu le temps d'approfondir.

Bon courage. J'ai vécu ça avec JDBC et j'en ai bavé avant d'obtenir le
résultat attendu.


Ca m'intéresserait de savoir de quelle manière vous avez résolu le
problème...

Francis JUGE-BOIRARD


Avatar
Hervé AGNOUX
Glop wrote:


- ne pas appeler pack !


Dans ce cas on obtient un petit rectangle qu'il faut redimensionner à la
main pour voir apparaître tous les champs. Ce n'est pas envisageable.



Oui mais dans ce cas, est-ce que le temps d'affichage est le même ? Lors
du
redimenssionnement, est-ce que le réaffichage prend beaucoup de temps ?


Non là c'est immédiat.


Et l'affichage reste bon ?? (à part que c'est une petite fenêtre) J'avoue
avoir du mal à comprendre comment une telle chose est possible... Que ce
soit par pack ou par autre chose, il faut bien en passer par le chargement
du contenu et la disposition des visuels ?...

Essaie en remplaçant le pack par un setSize(uneDimensionCorrecte) pour
voir...

Et c'est le pack de quoi ? Directement de la JFrame ou d'une JFrame perso ?


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




Avatar
mei


Mon expérience java est relativement neuve mais quand même, c'est un langage
plutôt blindé par rapport à C++. Comment peut-il y avoir des fuites
mémoires, même si c'est la faute du programmeur ? En plus même si la
conception s'est faite en même temps que la réalisation l'appli est loin
d'avoir été codée par des manchots.


Nul n'est à l'abris d'une fuite de mémoire ;)
En java, souvent elles arrivent lorsqu'on garde des références d'objets
obsolètes dans une collection : bien qu'obsolète, le gc n'a aucun moyen
de le savoir.

Avatar
Maxime Daniel
On Feb 19, 10:48 pm, mei wrote:



Mon expérience java est relativement neuve mais quand même, c'est u n langage
plutôt blindé par rapport à C++. Comment peut-il y avoir des fuit es
mémoires, même si c'est la faute du programmeur ? En plus même si la
conception s'est faite en même temps que la réalisation l'appli est loin
d'avoir été codée par des manchots.


Nul n'est à l'abris d'une fuite de mémoire ;)
En java, souvent elles arrivent lorsqu'on garde des références d'obje ts
obsolètes dans une collection : bien qu'obsolète, le gc n'a aucun moy en
de le savoir.


Pour abonder dans votre sens, je dirais même pire : Java crée une
espèce de sentiment de sécurité tout-à-fait trompeur.
Le garbage collector va effectivement récupérer les objets libres (ou
réputés tels, voir les weak collections). Mais tout objet que le
programme continue de référencer reste en mémoire. (Les machines
virtuelles sont plus ou moins douées pour détecter les petits cycles
et ce genre de choses. L'utilisation du JNI peut amener bien des
surprises.) Sur un petit programme qui ne sollicite pas beaucoup de
données et sort rapidement, Java dispense le programmeur de faire
l'effort de compréhension et tout se passe bien "par magie". Dès que
l'on veut manipuler des volumes conséquents ou écrire des programmes
destinés à s'exécuter longtemps, il faut autant de discernement et
presque autant de travail en Java qu'en C++.
Une bonne nouvelle toutefois : il existe des exemples de programmes
conséquents utilisés en 24/24 écrits en Java (par exemple les serveurs
d'application comme... ceux d'un certain nombre d'acteurs majeurs du
marché). Donc on peut faire confiance au langage sur cet aspect...


1 2