IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

AWT/Swing Java Discussion :

Mauvaises Performances sur MACOS


Sujet :

AWT/Swing Java

  1. #1
    Membre averti
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2022
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2022
    Messages : 61
    Par défaut Mauvaises Performances sur MACOS
    Bonjour,

    J'ai développé une application qui doit charger à partir d'une base de données une liste de près de 4000 entrées.
    Sous Windows cela marche très bien et ne prend à peine que 2 secondes. Sous MAC il faut énormément de temps et même au bout d'une heure ce n'est pas terminé.

    Je subodore un problème d'allocation dynamique différent sous OS/X et du Garbage Collector, mais je n'en suis pas sûr. Ou peut-être un problème de scrolling (je pencherais pour cela).

    Ce que je veut faire :

    Avoir une la liste avec les noms des items précédé par une case à cocher. En résumé, voici ce que je fais :

    - Allocation d'un JScroll
    - Ajout d'un JPanel dans le JScroll
    - Ajouts de mes lignes dans le JPanel.

    Au début j'avais essayé avec une JList mais sans succès.

    Voici une partie du code.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    	private void loadTitres()
    	{
    	 	try
    		{	 
    			java.sql.ResultSet rs =FilmTable.listerTitres("Titre_Francais");
    			if (rs== null) return;
    			while (true)
    			{
    				String titre =  rs.getString("Titre");	
    				if (isEmpty(titre)) continue ;  // ignore
    				JCheckBox cb = new JCheckBox(titre);
    				cb.setForeground(Color.WHITE);
    				cb.setBackground(Color.BLACK);
    	    		        monPanneau.add(cb);
    			}
    			rs.close(); 
    			monPanneau.revalidate();
    			monPanneau.repaint();	 
    		}
    		catch (Exception ex) { Common.afficherErreur(ex,"MaClasse","loadTitres");}
     
    	}
    Merci pour vos conseils, ou même une autre façon de programmer.
    Images attachées Images attachées  

  2. #2
    Membre très actif

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    496
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 496
    Billets dans le blog
    5
    Par défaut
    Vu de loin, mais de très loin:
    ressemble à une boucle infini.

    Il faudrait par:
    En gros, on continue à traiter tant qu'il y a des lignes retourné par la requête.

    Dans les remarques générales, il faut effectivement toujours fermer un stream, resultset, connexion...

    C'est pour ça que c'est Autoclosable et qu'il y a le try with ressources soit:
    try(rs =FilmTable.listerTitres("Titre_Francais))
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    try(rs =FilmTable.listerTitres("Titre_Francais))
    Plus besoin du finally pour fermer le tout. D'ailleurs ton code est faux sur ce point. Si il y a une exception, rien est dit que le resultset sera fermé.

    Donc avant, rs.close(), c'était le finally. Depuis Java 7, try-with ressource.

    Enfin, il faut décomposer les problème. Les problèmes d'IHM n'ont rien à voir avec les problèmes de recherche en BDD...

    Une classe qui manipule une IHM ne doit rien savoir de la BDD, et donc ne pas manipuler des objet de BDD (comme un Resultset).

    Après, si il y a des millions de lignes retourné par la requête, ça sera effectivement toujours lent.

  3. #3
    Membre averti
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2022
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2022
    Messages : 61
    Par défaut
    Merci Philippe,

    Je suis honteux, car depuis des années où je lis des base de données, je n'aurais jamais dû écrire while(true).
    *
    En général j'utilise while (rs.next())

    Merci aussi pour les conseil pour clore le ResultSet. Je vais ajouter un finally, mais ici je suis en test et par flemmardise, je n'ai pas encore géré les erreurs.

    Merci encore beaucoup pour ton aide.

  4. #4
    Membre très actif

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    496
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 496
    Billets dans le blog
    5
    Par défaut
    Finally, c'est juste à Java 6. Depuis Java 7, c'est try-with-ressources (ce qui simplifie le code, et évite le finally).

  5. #5
    Membre averti
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2022
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2022
    Messages : 61
    Par défaut
    J'ai modifié le code pour éviter la boucle sans fin. Toutefois j'ai le même phénomène.
    J'ai ajouté un message au début et à la fin du chargement.
    Je constate que le chargement sous MAC est comme sous Windows. Ce n'est donc pas le problème de mémoire. Quand je scrolle c'est très très très lent....

    J'ai modifié le code comme suit.

    Tu as raison. Je ne devais pas passer un rs. En général je ne repasse que les objets un par un. Mais c'est un vieux code sur lequel je m'appuie, et je vient d'ajouter une méthode dans FilmTable.

    Toutefois comme je viens de le dire, cela n'a pas vraiment d'impact sur le scrolling qui reste le problème.

    Merci encore.

    Gégé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
     
    	       System.out.println("démarrage du chargement.");
    	 	try
    	 	{	 
    			Vector<Film> v  =FilmTable.vecteurDesTitres("Titre_Francais");
    			if (v == null || v.size() == 0 ) return;
    			for (Film f : v)
    			{
    				if (f==null) break;
    				String titre =  f.Titre_Francais;	
    				if (isEmpty(titre)) continue ;  // ignore
    				JCheckBox cb = new JCheckBox(titre);
    				cb.setForeground(Color.WHITE);
    				cb.setBackground(Color.BLACK);
    	    		monPanneau.add(cb);
    			}
     
    		 monPanneau.revalidate();
    		 monPanneau.repaint();
    		 System.out.println("Chargement terminé");
    		}
    		catch (Exception ex) { Common.afficherErreur(ex,"Accueil","loadTitres");}
     
    	}

  6. #6
    Membre très actif

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    496
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 496
    Billets dans le blog
    5
    Par défaut
    Il faut éviter les Vector et préférer les collections(en général les List)

    Toujours dans les bonnes pratiques, une méthode qui renvoie une liste (comme ici .vecteurDesTitres()) doit, dans le pire des cas envoyer une collection vide, ce qui évite les NullPointerException.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if (v == null || v.size() == 0 ) return;
    Ne devrait pas exister.

    De même
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if (f==null) break;
    Aussi. Dans la collection ou liste, on ne met que ce qui doit être traité.

    Après, pour le fond du problème, si problème de performance il y a, c'est, à mon avis, dans FilmTable.vecteurDesTitres("Titre_Francais");

  7. #7
    Membre averti
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2022
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2022
    Messages : 61
    Par défaut
    Merci Philippe pour tes conseils, en fait je renvoie toujours un vecteur vide. C'est pas acquis de conscience que je teste le vecteur null. Par habitude, j'utilise Vector car sa taille ne change pas dans mon application (même si les vecteurs sont synchronisé et pas les listes). Dans le même contexte j'avais fait des essais et je n'ai pas perçu de différences notables pour ce qui est des performances.

    Si nous revenons à mon souci de performances, au début je pensais comme toi. J'ai donc créé un programme test sans accès à une base de données et j'ai le même comportement. Voir le code ci-dessous, que tu peux tester toi même si tu as un MAC sous OSX.

    En analysant les performances, il semble qu'au moment ou j'essaie des lancer le scroll, le processeur monte pendant plusieurs secondes (voire des minutes) entre 95 et 98%. Comme je n'ai pas le problème avec des JList par exemple (même avec plus de lignes) , je suppose que c'est dû à la façon dont le panneau est construit. Mais je n'ai pas compris pourquoi car sous windows, le problème n'existe pas. Est-ce un problème de JVM ? Je pense aussi au Garbage Collector.

    Merci encore.

    Gégé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
     
     
    	import javax.swing.JScrollPane;
    	import javax.swing.border.LineBorder;
    	import java.awt.GridLayout;
    	import javax.swing.JCheckBox;
    	import javax.swing.JFrame;
    	import javax.swing.JPanel;
    	import javax.swing.JButton;
    	import java.awt.event.ActionListener;
    	import java.awt.event.ActionEvent;
    	import java.awt.Color;
    	import javax.swing.JLabel;
     
    	public class Test extends javax.swing.JDialog 
    	{ 
    		private static final long 	serialVersionUID = 1L;
    		private JScrollPane 		Scroll;
    		private JPanel 			myPanel ;
    		private JButton 			Return;
    		private JLabel 			Message;
     
     
    		public  Test(JFrame jf) // Constructeur
    		{
    			super(jf,true);
     
    			setSize(416,644);
    			getContentPane().setLayout(null);
    			getContentPane().setBackground(Color.BLACK);
    			LineBorder border = new LineBorder(Color.YELLOW, 3);
    			getRootPane().setBorder(border); 
    			this.setUndecorated(true);
     
    			myPanel = new JPanel();
    				myPanel.setBackground(Color.BLACK);
    				myPanel.setLayout(new GridLayout(0, 1)); 
     
    			Scroll = new JScrollPane( ); 
    			        Scroll.setViewportView(myPanel);
    				Scroll.setBounds(10, 10, 393, 535);
    				Scroll.setLocation(10, 10);
     
    			Return = new JButton("Return");
    				Return.setBounds(152, 582, 89, 23);
    			        Return.addActionListener(new ActionListener() 
    				{
    					public void actionPerformed(ActionEvent arg0) { finish();}
    				});
     
     
    			Message = new JLabel("Cocher les lignes à conserver.");
    				Message.setForeground(Color.CYAN);
    				Message.setBounds(20, 557, 375, 14);
     
    			getContentPane().add(Scroll);
    			getContentPane().add(Return);
    			getContentPane().add(Message);
     
    			loadTitres();
    			this.setLocationRelativeTo(null);
    			setVisible(true);
    		}
     
    		private void  finish()
    		{
    			this.setVisible(false);
    			return;
    		}
     
    		private void loadTitres()
    		{
    			System.out.println("Début du chargement.");
    		 	try
    		 	{	 
    				String line = "Ceci est la ligne  : ";
    				for (int i =0; i<7000; i++)
    				{
    					String curline =   line + (i+1) ;
    					JCheckBox cb = new JCheckBox(curline);
    					cb.setForeground(Color.YELLOW);
    					cb.setBackground(Color.BLACK);
    		    		myPanel.add(cb);
    				}
    				myPanel.revalidate();
    				myPanel.repaint();
    				System.out.println("Fin du chargement");
    			}
    			catch (Exception ex)  {	System.out.println("Erreur de chargement");} 
     
    		}
     
    		public static void main(String[] args) 
    	    {
    			  new Test(new JFrame());
    	    }
    }

  8. #8
    Membre très actif

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    496
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 496
    Billets dans le blog
    5
    Par défaut
    Moi, j'ai pas de problème (je suis sous Windows).
    Nom : dev_2023_01_20.png
Affichages : 154
Taille : 211,4 Ko

    Là, ça ne peut être qu'un problème d'implémentation de la JVM, sur lequel on ne peut pas faire grand chose.

    C'est quelle ligne où ça ralenti (si on regarde pas à pas en debugage)?

  9. #9
    Membre très actif

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    496
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 496
    Billets dans le blog
    5
    Par défaut
    Un autre détail: Le CG, il vit sa vie et tu ne peux rien y faire. System.gc() est:
    1) A proscrire.
    2° Invite le CG à passer. Mais il n'est pas dit qu'il va passer.

  10. #10
    Membre averti
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2022
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2022
    Messages : 61
    Par défaut
    Comme je l'ai écrit, sous Windows je n'ai aucun problème.

  11. #11
    Membre très actif

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    496
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 496
    Billets dans le blog
    5
    Par défaut
    Oui, mais sous Mac OS, quand tu debug (Eclipse/IntelliJ...), c'est quelle ligne où il rame?

  12. #12
    Membre averti
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2022
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2022
    Messages : 61
    Par défaut
    Si je teste sous éclipse en mode Debug , et il ne rame que lorsque j'essaie de scroller. Donc pas sur une instruction spéciale. Je n'ai pas encore essayé de mettre un listener sur le JScroll. C'est ce que je vais faire dans la prochaine étape pour essayer de comprendre ce qui se passe. Mais je ne suis pas certain que cela fera avancer les choses.

    J'ai essayé d'analyser les performance avec jconsole, et lorsque l'affichage des lignes est terminé, le taux d'occupation mémoire est de l'ordre de 280 M (j'ai mis le heap à 512M) et lorsque je lance le scrolling la CPU monte jusqu'à 90 ou 95 %. Pas de pagination (il n'y a que cette application qui tourne sur le MAC).

    Je pensais originellement que cela pouvait provenir du garbage collector, mais même en attendant plusieurs minutes avant de lancer le scrolling (le temps que la mémoire soit libérée) j'obtiens des performances désastreuses ou même des blocages.

    Avec plusieurs essais j'ai joué sur la taille du JPanel et du nombre de lignes. Jusqu'à environ 4000 lignes et un JPanel de size(300, 10000) le scrolling marche très bien. Mais si je monte à 5000 lignes, c'est terminé, le problème de blocage survient. Ce qui pourrait indiquer que c'est un problème de mémoire ce que dément apparemment les affichages de jconsole. Surtout que sous Windows avec les mêmes paramètres de lancement de Java, je n'ai pas le même résultat.

    Donc je suis un peu perdu dans l'analyse du phénomène. Mais comme j'ai horreur de ne pas comprendre, je continue mes investigations.

    Quoi qu'il en soit, merci encore Philippe d'essayer de m'aider.

    Gégé

  13. #13
    Membre averti
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2022
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2022
    Messages : 61
    Par défaut
    J'ai résolu mon problème en changeant complètement la structure du programme.
    A la place de charger les JCheckBox dans un JPanel, j'ai défini une JTable à 2 colonnes, une avec les checkboxes et l'autre avec les lignes.
    C'est un peu plus compliqué car pour avoir exactement l'apparence précédente, j'ai dû définir une classe DefaultTableCellRenderer.

    Enfin ça marche même très vite.

    Merci encore*

    Gérard

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [9.3] Mauvaises performances sur SELECT
    Par marsup077 dans le forum Administration
    Réponses: 4
    Dernier message: 26/03/2015, 15h26
  2. Mauvaise performance sur table partitionnée
    Par Bilna dans le forum Oracle
    Réponses: 3
    Dernier message: 14/02/2011, 18h25
  3. Drawing performance sur macos
    Par Tosh dans le forum Apple
    Réponses: 0
    Dernier message: 20/01/2011, 09h51
  4. Mauvaise performance d'opengl sur vista
    Par clemsye dans le forum Installation
    Réponses: 5
    Dernier message: 01/09/2008, 16h15
  5. [Crystal] Performance sur grosses base de données
    Par Nico118 dans le forum SAP Crystal Reports
    Réponses: 5
    Dernier message: 14/11/2003, 16h27

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