1. #1
    Membre du Club
    Profil pro
    Inscrit en
    mai 2006
    Messages
    137
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mai 2006
    Messages : 137
    Points : 64
    Points
    64

    Par défaut [performance] A quoi bon augmenter la mémoire disponible ?

    Salut,

    Je développe une appli de simulations numériques, avec une interface graphique "en temps réel" basée sur JFreeChart.
    En début de simulation, je constate des "à-coups" gênants, puis le déroulement de la simulation devient plus fluide.
    Ainsi :
    Nom : speed1.png
Affichages : 60
Taille : 74,5 Ko

    L'analyse de la mémoire montre que la gestion de la mémoire allouée à l'application est responsable de ces "à-coups" :
    Nom : memory1.png
Affichages : 61
Taille : 47,2 Ko

    Pour essayer d'obtenir une simulation plus fluide, j'augmente la mémoire allouée à l'application (-Xmx2048m -Xms1024m).
    Je relance, et j'obtiens :
    Nom : speed2.png
Affichages : 60
Taille : 86,0 Ko
    et :
    Nom : memory2.png
Affichages : 60
Taille : 47,7 Ko

    La simulation est beaucoup plus fluide, parce qu'il n'est plus nécessaire d'augmenter la taille du heap en début de simulation.
    En revanche, le rythme des collectes est beaucoup plus élevé, avec pour résultat, au total, un ralentissement de la simulation :
    - dans la première configuration, la durée d'une simulation tourne autour de 60 secondes,
    - dans la deuxième configuration, la durée d'une simulation tourne autour de 45 secondes.

    Pourquoi le fait d'avoir alloué plus de mémoire à l'application augmente-t-il la fréquence des collectes ?
    Que faire pour concilier fluidité et performance ?

  2. #2
    Membre averti
    Homme Profil pro
    Inscrit en
    octobre 2011
    Messages
    224
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : octobre 2011
    Messages : 224
    Points : 367
    Points
    367

    Par défaut

    Les "à-coups" c'est le ramasse miettes, ou garbage collector, qui libère la mémoire des objets qui ne sont plus utilisés (plus référencés).
    Cet excellent article te donneras toutes les informations dont tu as besoin: http://jmdoudoux.developpez.com/cour...on_memoire.php
    Quant à concilier fluidité et performance, il y aura nécessairement des compromis à faire, il y en a toujours avec la JVM standard et cela dépend énormément de ton application.
    Il va falloir que tu fasses des tests avec différentes options, à commencer par l'algorithme à utiliser par le garbage collector pour traiter les collections (incrémental, série, parallèle, concurrent, ...), la taille de la mémoire à allouer en fonction de ton application, les ratios entre les parties "young" et "old".

  3. #3
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    avril 2007
    Messages
    25 111
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : avril 2007
    Messages : 25 111
    Points : 48 013
    Points
    48 013

    Par défaut

    Il faut voir aussi avec quel garbage collector tu travaille. Il y a plusieurs algorithmes, et le GC par défaut dépend de la version de la jvm que tu utilise. Tu pourrais aussi regarder la complexité de te graphes d'objet, voir comment réutiliser tes objets plutôt que de le jeter et d'en créer de nouveau.
    David Delbecq Java Software engineer chez Trimble. TRANSPORT & LOGISTICS.     LinkedIn | Google+

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    mai 2006
    Messages
    137
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mai 2006
    Messages : 137
    Points : 64
    Points
    64

    Par défaut

    Apparemment, l'algorithme du GC est, par défaut, Parallel collector.
    J'ai essayé chacun des autres, sans y gagner.
    Le Concurrent mark-sweep collector permet de bien lisser les simulations, en faisant disparaître les à-coups, mais au prix du doublement des durées des simulations.

    Ce qui me surprend le plus, c'est que le comportement du GC varie beaucoup pour des simulations qui sont (au moins à première vue) à peine différentes :

    Simulation 1 (exécutée en 54 s) :

    Nom : sim1.png
Affichages : 19
Taille : 28,6 Ko

    Simulation 2 (exécutée en 120 s) :

    Nom : sim2.png
Affichages : 19
Taille : 28,5 Ko

    Pourtant l'algorithme est le même dans les deux cas (Parallel collector).
    J'ai du mal à comprendre ce qui, dans les différences entre les deux simulations, induit de telles différences de comportement du GC, avec de telles conséquences néfastes pour les performances (doublement du temps d'exécution !).

  5. #5
    Membre averti
    Homme Profil pro
    Inscrit en
    octobre 2011
    Messages
    224
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : octobre 2011
    Messages : 224
    Points : 367
    Points
    367

    Par défaut

    Au vu des deux profils mémoire, dans le scénario 1 à peu prés 300Mo sont traités par le gc et à peu prés 1Go dans la simulation 2, donc rien de surprenant dans le doublement du temps d'exécution.
    il semble donc que les scénarios 1 et 2 soient plus différents qu'il n'y paraît.
    Quant aux différences de comportement du GC, l'algorithme utilisé peut être adapté pour une simulation et pas pour une autre, c'est toute la problématique "d'ajustement" et de compromis dont je parlais.
    Pour aller plus loin, il faudrait comme le suggère tchize analyser la complexité de tes graphes d'objets en mémoire.
    Une fois que c'est fait, ça peut aller de simples modifications comme la réutilisation d'objets plutôt que la création systématique de nouveaux objets, de l'utilisations de collections plus performantes, ...
    Il n'y a pas de recette magique dans ce genre de problématiques, ça prend du temps.

  6. #6
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    avril 2007
    Messages
    25 111
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : avril 2007
    Messages : 25 111
    Points : 48 013
    Points
    48 013

    Par défaut

    faire un peu de profiling pour trouver les vrais coupable, c'est aussi utile. Là pour le moment on vois une corrélation entre les temps d'exécution et les GC. Mais est-ce le GC qui bloque, ou l'inverse, le GC qui a enfin l'occasion de travailler quand l'application fait un lourd calcul ne requiérant plus la création de mémoire?
    Garder autant que possible aussi les objets temporaires à l'intérieur des fonctions (création / utilisation / destruction) sans les faire fuiter, peut aussi pas mal aider le GC. En effent la JVM est capable d'allouer ces objets directement sur la pile, pour autant qu'elle aie la garantie qu'ils ne peuvent pas fuiter, et ainsi se passer de les rajouter dans le GC.
    David Delbecq Java Software engineer chez Trimble. TRANSPORT & LOGISTICS.     LinkedIn | Google+

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    mai 2006
    Messages
    137
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mai 2006
    Messages : 137
    Points : 64
    Points
    64

    Par défaut

    La grosse différence entre les simulations 1 et 2, c'est que la seconde enregistrait plus d'informations disponibles pour être éventuellement affichées dans l'interface graphique.
    Je me suis interrogé sur la façon que j'avais de stocker ces données, au moyen d'une grande quantité de HashMap à la durée de vie éphémère (quelques périodes sur les milliers que compte une simulation).
    J'ai complètement remis en cause ce choix, remplaçant les HashMap par de simples tableaux, au prix d'un gros effort de réécriture de toute cette partie du simulateur.

    Bilan : multiplication par deux de la vitesse des simulations, et déroulement très fluide.

    Ci dessous, l'utilisation de la mémoire, pour la simulation 2 (avec -Xms1024m -Xmx2048m):

    Nom : sim2.png
Affichages : 10
Taille : 31,4 Ko

Discussions similaires

  1. Augmenter la mémoire virtuelle
    Par kenny6 dans le forum Général Java
    Réponses: 6
    Dernier message: 12/12/2007, 09h52
  2. [C#][.NET 2.0]Augmentation de mémoire
    Par genki dans le forum Général Dotnet
    Réponses: 6
    Dernier message: 25/04/2007, 10h04
  3. commetn augmenter la mémoire
    Par chouchou93 dans le forum Eclipse Java
    Réponses: 14
    Dernier message: 27/06/2006, 12h09
  4. Struts-Hibernate-EJB : A quoi bon ?
    Par n@n¤u dans le forum Struts
    Réponses: 2
    Dernier message: 09/05/2006, 10h05
  5. [MFC] Augmentation en mémoire
    Par pitch21 dans le forum MFC
    Réponses: 21
    Dernier message: 20/07/2004, 13h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo