Jtree x Custom CellRenderer x CardPanel -> Memoire qui explose

Jtree x Custom CellRenderer x CardPanel -> Memoire qui explose - Java - Programmation

Marsh Posté le 22-09-2004 à 10:15:12    

Voila après quelques recherches infructueuses (peut être une mais le thread parlait de l'utilisation en memoire importante d'un gros Jtree) je viens vous demander si par experience vous avez deja rencontrer un tel probleme.
 
Pour des besoins fonctionnels, j'ai donc, plusieurs arbres liés sur des données en 3 tiers, affichés dans un CardPanel. Lorsque je navigue sur une clé, tous les cardPanel sont effaces, et un nouveau Jtree est affiché dans une nouvelle page du CardPanel.
 
Ce Jtree a un cellRenderer qui lui permet d'afficher au niveau des noeuds, selon le contenu des informations, une ou plusieurs icones.
 
Jusque la, tout va bien, le probleme arrive au bout de qqs navigations, ou la lenteur d'un même traitement se fait sentir, je vérifie la mémoire, paf, le process javaw augmente sans cesse, jusqu'a tout bloquer. Un coup de memory Profiler, me montrera que les si simples JPanels et JLabels construits dans le cellRenderer, me bouffent tout, et ne sont jamais collectés.
 
Ni une ni deux, je trouve un bon endroit pour faire, un System.gc(), mlais c'est pareil, alors je me fais un petit KillAllListners, et je place qqs removeAll qui vont bien (jusqu'a tous les Nodes du JTree a effacer), mais hélas, c'est pareil.
 
En gros, je ne vous demande pas directement une solution ( haha sauf si vous avez de la magie pure, je suis preneur :) ), mais plutôt si vous avez déja été confrontés à ce genre de probleme et la technique/méthode que vous avez employés pour vous en sortir :)
 
Merci d'avance !
 
 

Reply

Marsh Posté le 22-09-2004 à 10:15:12   

Reply

Marsh Posté le 22-09-2004 à 10:16:45    

Tu peut poster le code de ton CellRenderer ?

Reply

Marsh Posté le 22-09-2004 à 10:18:27    

On ne fait jamais un System.gc() soi-même, surtout pas dans une interface graphique !!!!
 
On peut voir tout le code de la chose stp ? tu gardes des références où il ne faudrait pas.

Reply

Marsh Posté le 22-09-2004 à 10:20:33    

concernant, la méthode, je suppose que tu n'utilises pas le renderer selon la recette préconnisée et que tu crées un nouvel objet à chaque rendering, ce qui serait complètement à l'inverse du pattern de la peinture au tampon.

Reply

Marsh Posté le 22-09-2004 à 10:23:05    

Voici le code du CellRenderer qui me chagrine, le HistoryTree est le composant qui permet les navigations, et qui integre les CardPanels qui eux même integrent les JTree :)
 
Je viens du C++, et c'est vrai que depuis qqs temps je suis moins attentif aux histoires de memoires sous java, belle erreur :).
 

Code :
  1. public class ComplexCellRenderer extends JUTreeCellRenderer
  2. {
  3. private HistoryTree historyTree;
  4. public ComplexCellRenderer( HistoryTree historyTree )
  5. {
  6.  this.historyTree = historyTree;
  7. }
  8. public Component getTreeCellRendererComponent( JTree tree, Object value, boolean sel, boolean expanded,
  9.                         boolean leaf, int row, boolean hasFocus )
  10. {
  11.  Component cmp = super.getTreeCellRendererComponent( tree, value, sel, expanded, leaf, row, hasFocus() );
  12.  JPanel   panel = new JPanel();
  13.  // root
  14.  if( tree.getModel().getRoot().equals( value ) )
  15.  {
  16.   panel.add( new JLabel( CiTree.mVeryRootDisplayName ) );
  17.   panel.setOpaque( true );
  18.   panel.setBackground( Color.WHITE );
  19.   panel.setVisible( true );
  20.  }
  21.  else // nodes
  22.  {
  23.   Icon          icon = null;
  24.   DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
  25.   if( !node.equals( null ) )
  26.   {
  27.    if( node.getUserObject() == "$place-holder$" )
  28.     return cmp;
  29.    JUTreeNodeBinding tnb = (JUTreeNodeBinding)( node.getUserObject() );
  30.    if( !tnb.equals( null ) )
  31.    {
  32.     if( tnb.getRow() == null )
  33.      return cmp;
  34.     CiHierViewRow hierRow = (CiHierViewRow)tnb.getRow();
  35.     // if node doesn't have sons, then delete the $place-holder$ "virtual" DefaultMutableTreeNode.
  36.     if( hierRow.getChildrenCount() == 0 )
  37.      node.removeAllChildren();
  38.     // geo/tech icon
  39.     JLabel defLabel = new JLabel( SimpleCellRenderer.getIcon( hierRow.getNodeIcon() ) );
  40.     defLabel.setText( " - " );
  41.     panel.add( defLabel );
  42.     Icon[] relationIcons = historyTree.getRelationIcons();
  43.     // TODO Name list of icon to intercept the system icon
  44.     // actually this icon is in position 0, so we start with 1
  45.     for( int i = 1; i < relationIcons.length; ++i )
  46.      if( hierRow.hasRelation( i ) )
  47.       panel.add( new JLabel( relationIcons[ i ] ) );
  48.     // display retrieved info
  49.     setText( hierRow.getNodeDisplayText() );
  50.     // disable the "default" icon
  51.     setIcon( null );
  52.    }
  53.   }
  54.   if( cmp != null )
  55.   {
  56.    cmp.setVisible( true );
  57.    cmp.doLayout();
  58.    cmp.repaint();
  59.    cmp.setBackground( Color.BLUE );
  60.    panel.add( cmp );
  61.    panel.setOpaque( true );
  62.    panel.setBackground( Color.WHITE );
  63.    //panel.setBackground( Color.RED );
  64.    panel.setVisible( true );
  65.   }
  66.  }
  67.  return panel;
  68. }
  69. }

Reply

Marsh Posté le 22-09-2004 à 10:38:11    

bon, je te fais le topo.
 
tu construis un JPanel que tu renvoies à chaque coup de peinture (soit très très souvent, imagines un scrolling).
 
au moment de peindre le composant appelle getTreeCellRendererComponent, il accroche le composant renvoyé comme enfant de lui-même, le layout et fait la peinture. Et il ne le vire pas, dans l'espoir que tu vas le réutiliser.
 
D'autre part, il est très très fortement déconseillé (voire interdit) de créer un composant dans cette méthode on doit modifier toujours le même composant.
 
bref, ce mécanisme est un mécanisme de *réutilisation*, tu dois donc *réutiliser*.
 
voilou
 
des détails : je vois un doLayout(), un repaint() ça c'est pelle à clous. 1) ça risque pas de peindre tant que c'est pas aggrégé dans un autre composant 2) ça risque pas de layouter tant qu'on a pas aggrégé dans un autre composant (on sait pas encore la place disponible) 3) ça n'a rien à foutre là. On est dans une méthode qui doit être aussi rapide que possible on est pas là pour prendre le café.

Reply

Marsh Posté le 22-09-2004 à 10:39:33    

Reply

Marsh Posté le 22-09-2004 à 10:48:55    

Effectivement si on a pas le droit de creer des objets la dedans, ça change tout, je n'ai plus qu'a me creer une chieé d'icones qui representent toutes les possibilites d'affichages, ou de les creer dynamiquement.
 
Merci de l'info :)

Reply

Marsh Posté le 22-09-2004 à 10:51:01    

nan, tu peux les créer la première fois que tu en as besoin par exemple, mais tu dois réutiliser après.
 
D'autre part, pour les ciones, tu es libre, je te parle pour les composant.
 
on peut avoir une capture d'écran du JTree avant que tu le casses STP ? pour voir si on peu pas simplifier un peu.

Reply

Marsh Posté le 22-09-2004 à 11:03:14    

Voila la bête :)
 
Les differents Tree sont liés par une action ( les fleches en gros ) qui ouvre le Tree lié sur le CardPanel voisin, on peut naviguer dans l'historique, cependant une navigation sur un champ fait repartir l'historique à zéro. Ca peut paraitre compliquer a utiliser, mais finalement c'est tres souple, d'autant plus que je n'ai pas eu le choix :p !
 
http://www.omitofa.com/jogrey/pics/HistoryTree.jpg

Reply

Marsh Posté le 22-09-2004 à 11:03:14   

Reply

Marsh Posté le 22-09-2004 à 11:10:48    

mouais, mets directement des JLabel dans ton tableau au lieu de simplement des Icones, ça me parrait le plus simple ...
 
utilise toujours le même JPanel.

Reply

Marsh Posté le 22-09-2004 à 11:47:49    

J'ai compris le mécanisme ! J'ai comme vous m'avez conseillé, utilisé un seul et même JLabel/JPanel etc, et c'est beaucoup beaucoup mieux !!
 
Ils n'empestent plus la mémoire, et je peux faire beaucoup de navigation avant que la mémoire soit pleine a nouveau, mais cette fois ci ne n'est plus ma faute, mais le JUTreeNodeBinding qui me cree des mega octets d'objets non collectes :)
 
Je vais voir de ce cote la à présent !
 
Merci pour tout !


Message édité par jogrey le 22-09-2004 à 14:04:14
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed