probleme de memoire de la VM java - Java - Programmation
Marsh Posté le 05-05-2006 à 14:20:19
Et en affectant "encore plus" de mémoire ?
Marsh Posté le 05-05-2006 à 15:43:13
slt,
jai meme essaye de mettre -Xmx512m mais ca n etoujours pas fonctionner.........
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at java.lang.String.codePointAt(String.java:589)
at java.lang.String.toLowerCase(String.java:2213)
at java.lang.String.toLowerCase(String.java:2277)
at exemples.XmlLogLine.isStart(XmlLogLine.java:283)
at exemples.TreeDemo.createNodes(TreeDemo.java:187)
at exemples.TreeDemo.createNodes(TreeDemo.java:190)
at exemples.TreeDemo.createNodes(TreeDemo.java:190)
....................
donc des idees les gars, svp...
Marsh Posté le 05-05-2006 à 15:52:58
ton fichier .obj, c'est du XML ? Tu utilises quoi pour le parser ?
Marsh Posté le 05-05-2006 à 15:58:37
le fichier *.objcest une serialisation dune classse java...(objet)
en fait on est deux sur ce projet et cest lautre etudiant qui est charge de parser le fichier et il ma dit qu'il utuilisait JDom.
Marsh Posté le 05-05-2006 à 16:10:26
Si c'est juste de la sérialisation d'objets Java, je ne vois pas pourquoi tu as besoin de JDOM pour ça
Marsh Posté le 05-05-2006 à 16:13:34
ben je ne sais pas trop pourquoi il utilise JDom...
mais au depart on a un fichier log sous format *.txt et ce fichier il le transforme en XML ... puis il serialise lobjet java pour obtenir le fichier *.objet...
Marsh Posté le 05-05-2006 à 16:28:46
Comme ça, vu de loin on dirait bien qu'il y a une couche XML qui n'a pas lieu d'être.
Et si vous passez par une sérialisation sur le disque, c'est parce que vous avez besoin de sauvegarder l'arbre ou c'est pour passer les objets d'une appli java à une autre.
Attention : si c'est pour passer l'arbre d'un module de l'appli à un autre (donc dans la même JVM) là encore ça serait une couche inutile
Marsh Posté le 05-05-2006 à 16:35:29
en fait la serialisation de lobjet ne sauvegarde sur le disque que des donnees qui seront ensuite affectees a larbre (larbre en lui meme nest pas sauvegarde sur le disque).......moi je recupere le fichier .obj qui contient des donnees relatids a larbre... que je deserialise puis je parcours la collection...en recuperant les parties de donnees necesaires a la creation de larbre....
Marsh Posté le 05-05-2006 à 16:45:08
je mexplique plus clairement...........au depart on a un fichier txt de log que mon binome transforme en fichier XML......puis ce fichier XML est serialise sur le disque en tant que collection......puis moi je recupere cette collection que je parcours en fonction de mes besoins pour larbre...
Marsh Posté le 05-05-2006 à 16:54:22
La question qui se pose c'est "Est-ce qu'il y a 2 applications java ?"
Une pour le parsing du fichier txt et une autre pour la création de l'arbre ?
Marsh Posté le 05-05-2006 à 17:04:09
ben vu que nous travaillons chaucun chacun sur notre poste.......il a sa propore application java qui fait le parsing et moi jai mon appliaction de mon cote qui permet de creer larbre....mais jutilise bien des classses et des fonctions de deserialisation que me fournit mon binome.....
Marsh Posté le 05-05-2006 à 17:14:45
Ok, donc maintenant on peut revenir au problème d'origine : le OutOfMemoryError
Apparemment tu as eu StackOverflowError quand tu as augmenté la mémoire disponible.
J'en déduis que tu utilises de la récursivité et il est probable que la condition d'arret de récursivité soit mauvaise !
Marsh Posté le 05-05-2006 à 17:29:08
oui effectivement jutilise de la recursivite ....
voici le code la fonction qui cree larbre:
private DefaultMutableTreeNode createNodes(Iterator i,DefaultMutableTreeNode racine) {
DefaultMutableTreeNode noeud = null;
XmlLogLine tmp = new XmlLogLine();
while(i.hasNext()){
tmp = (XmlLogLine)i.next();
racine.setAllowsChildren(true);
noeud = new DefaultMutableTreeNode(tmp.getLog_method());
if(tmp.isStart() && !(tmp.isStartStop())){
(tmp.getLog_method());
racine.add(noeud);
createNodes(i,noeud);
}
else if(tmp.isStop() && !(tmp.isStartStop())){
racine=(DefaultMutableTreeNode)racine.getParent();
}
else if(tmp.isStartStop()){
(tmp.getLog_method());
racine.add(noeud);
}
}
return racine;
}
mais ce qui me parait bizarre cest le fait que cette fonction marche tres bien lorsque jai essaye de faire larbre a partir dun fichier moins lourd(1Mo)... il me le cree sans probleme alors que quqnd jessaie avec un fichier beaucoup plus gros il me plante avec cette error de overflow....donc si tu/vous voit/voyez lerreur, je serais enchante de corriger cette erreur...
Marsh Posté le 05-05-2006 à 17:31:48
c'est du récursift ton truc ... mesure la profondeur maximale à tout hasard.
Marsh Posté le 05-05-2006 à 17:34:15
comment je fais pour mesurer la profondeur maximale de mon arbre??
Marsh Posté le 05-05-2006 à 18:06:06
Montre nous :
- la ligne de code qui lance le 1er createNodes
- la taille de ta collection
- le code des méthodes isStart() isStop(), isStartStop()
- getLog_method(), ça fait quoi ?
- XmlLogLine tmp = new XmlLogLine(); => OUTCH !!! ce new ne sert à rien car tmp est réaffecté juste derrière !
Marsh Posté le 05-05-2006 à 18:28:02
cest le constructeur de ma class pricipal TreeDemo qui lappelle:
-cest lappele du premier createNodes
public TreeDemo() {
super(new GridLayout(1,0));
XmlLogCol result = new XmlLogCol();
result.unSerialize("C:\\Documents and Settings\\karnan\\My Documents\\RECUPERER_DEPUIS_PROJECT31\\Projet_interface_graphique_java\\gemprojetvincent\\Gemlca\\test.obj" );
Iterator i = result.iterator();
DefaultMutableTreeNode racine =
new DefaultMutableTreeNode(((XmlLogLine)i.next()).getLog_method());
createNodes(i,racine);
//Create a tree that allows one selection at a time.
tree = new JTree(racine);
tree.getSelectionModel().setSelectionMode
(TreeSelectionModel.SINGLE_TREE_SELECTION);
//Create the scroll pane and add the tree to it.
JScrollPane treeView = new JScrollPane(tree);
}
-taille de la collection: 52Mo (le fichier obj)
-code des focntions:
public boolean isStart()
{
return (this.getLog_message().toLowerCase().indexOf("start" ) >= 0);
}
public boolean isStop()
{
return (this.getLog_message().toLowerCase().indexOf("stop" ) >= 0);
}
public boolean isStartStop()
{
return (this.isStart() && this.isStop());
}
-get log methode focntion:
elle retourne lattribut (log_method) dun objet contenu dans la collection
voici le code:
public String getLog_method()
{
return log_method;
}
- et jai enleve le new sur tmp et jai mis XmlLogLine tmp = null;et je laffecte juste derriere
Marsh Posté le 05-05-2006 à 19:23:22
pour la récursion, ben tu mets un compteur, et tu incrémentes à chaque appel récursif, et tu affiches le maximum
Marsh Posté le 09-05-2006 à 11:08:31
Premièrement, je pense qu'il y a un problème d'algo Malheureusement j'ai pas trop de temps pour t'en proposer un autre (je verai ça ce soir)
Les méthodes de test peuvent être optimisées :
- utilise directement l'attribut log_method au lieu de passer par this.getLog_method()
- définis les chaines "start" et "stop" en constantes dans ta classe
Code :
|
C'est à tester mais je pense que ça serait plus performant si tu utilisais les expressions régulières plutot que indexOf.
log_message.matches(".*start" ) retourne true ssi on rencontre la chaine start dans log_message
Ca serait encore mieux si tu avais le contrôle de la génération des message et si start et stop étaient toujours en minuscule (ou toujours en majuscule)
Citation : -taille de la collection: 52Mo (le fichier obj) |
C'est le nombre d'éléments dans la collection qui m'intéresse : result.size()
Marsh Posté le 09-05-2006 à 11:44:42
en fait jai plusieurs fichiers obj de la collection....
mais la collection que jutilise en ce moment contient 73763 elements...
et pour les fonctions isstart() et isstop().... jai pas trop le choix ce nest pas qui moccupe de cette partie, cest un autre etudiant......mais je ne manquerais pas de lui faire part.
merci
Marsh Posté le 09-05-2006 à 22:07:36
Alors attention, il va falloir s'accrocher !
J'ai appliqué la techique dite de l'invariant à ce que j'ai compris à ton problème d'algo (Cf. commentaire en début de boucle).
Si j'ai bien compris le problème (et si j'ai pas fait d'erreur...) ce qu'il en sort c'est un algo vérifié !
Code :
|
Et voici ce que je te propose pour optimiser un peut ta classe XmlLogLine
Code :
|
Marsh Posté le 10-05-2006 à 12:39:47
hello,
merci pour lalgo...
jai quand meme 2 ou 3 soucis...
comme:
-la fonction createNodes(List collection)....moi je ai a ma disposition seulement la serialisation dun objet du type XmlLogCol...et non une collection proprement dit...
voici comment je men sers:
[java] XmlLogCol result = new XmlLogCol();
result.unSerialize("C:\\Documents and Settings\\karnan\\My Documents\\RECUPERER_DEPUIS_PROJECT31\\Projet_interface_graphique_java\\gemprojetvincent\\Gemlca\\log.obj" );
createNodes(result);
[java]
voici la class XmlLogCollection:
[java]public class XmlLogCol implements Serializable
{
private static final long serialVersionUID = 1L;
static Logger logger = Logger.getLogger(XmlLogCol.class);
private LinkedList log;
private int debug = 0;
private int info = 0;
private int warn = 0;
private int fatal = 0;
private int error = 0;
private int account = 0;
public XmlLogCol()
{
super();
this.log = new LinkedList();
this.setAccount(0);
this.setDebug(0);
this.setInfo(0);
this.setWarn(0);
this.setFatal(0);
this.setError(0);
}
public XmlLogCol(LinkedList liste)
{
super();
this.log = new LinkedList(liste);
this.updateLevels();
}
public XmlLogCol(XmlLogCol xlc)
{
super();
this.log = new LinkedList(xlc.log);
this.updateLevels();
}
..............
............
}[java]
Marsh Posté le 10-05-2006 à 13:19:53
salut bidem,
bon finalement jai fait un test avec ton exemple avec une collection en parametre.....je donne en parametre la liste chaine (linked list) qui est un attribut de la classe XmlLogCol....jai compile mais le probleme cest que jai une exception:
exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: exemples.XmlLogLine
at exemples.TreeDemo.createNodes(TreeDemo.java:229)
at exemples.TreeDemo.<init>(TreeDemo.java:77)
at exemples.TreeDemo.createAndShowGUI(TreeDemo.java:309)
at exemples.TreeDemo.access$0(TreeDemo.java:291)
at exemples.TreeDemo$1.run(TreeDemo.java:324)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
Jai fait debuggage pour savoir ou ca plante et jai vu que cest au moment de depiler le sommet de la pile avec la fonction peek() quil y avait un probleme......au premier passage dans le while, la methode peek() ne pose pas de probleme, ni au 2eme, mais au 3eme passage il narrive pas a depiler kle sommet pourtant quand je regarde le sommet de la pile....il y a bien un element au sommet de la pile......je ne sais pas pourquoi il ya une exception cast.....
merci
Marsh Posté le 10-05-2006 à 15:21:21
Au temps pour moi, il y a une erreur d'étourderie dans mon code.
Avant de regarder la réponse, essaye de trouver par toi même sachant que ClassCastException veut dire qu'on essaye de faire un cast sur un objet de type incompatible
=> donc ce qu'on a mis dans la pile n'est pas une instance de DefaultMutableTreeNode
Code :
|
c'est le noeud qu'il fallait mettre dans la pile (et non la ligne)
et il vaut mieux utiliser push que add, ça fait "plus mieux" pour une Stack
Marsh Posté le 10-05-2006 à 15:26:52
eh ben cest :
if (ligne.isStop()) {
// en fait c'est un start/stop
// le nouveau noeud "peut" avoir des fils => on le met dans la pile
// si on est sûr qu'il y aura des fils déplacer le setAllowsChildren ici
pile.add(ligne);
}
ligne est du type XmlLogCol
Marsh Posté le 10-05-2006 à 15:38:07
et maintenant jai une nouvelle erreur:
Exception in thread "AWT-EventQueue-0" java.util.EmptyStackException
at java.util.Stack.peek(Stack.java:79)
at exemples.TreeDemo.createNodes(TreeDemo.java:229)
at exemples.TreeDemo.<init>(TreeDemo.java:77)
at exemples.TreeDemo.createAndShowGUI(TreeDemo.java:309)
at exemples.TreeDemo.access$0(TreeDemo.java:291)
at exemples.TreeDemo$1.run(TreeDemo.java:324)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
EmptyStackException: je pense quil essaie de depiler alors que la pile est vide, non???
je pense quil faut rajouter un test juste avant la ligne qui depile: du genre
[code]
if(!pile.empty()){
DefaultMutableTreeNode parent = (DefaultMutableTreeNode) pile.peek();
else return racine;
}
[code]
je sais pas si cest exactement cette erreur la......
Marsh Posté le 10-05-2006 à 15:39:29
D'après moi, la pile ne devrait jamais être vide car il devrait toujours y a voir au moins la racine dedans...
tu as bien remplacé le pile.add(ligne); par pile.push(noeud); ?
Marsh Posté le 10-05-2006 à 15:58:33
oui jai bien ajouter pile.add(ligne) par pile.push(noeud)...
et jai essaye de mettre un test comme je lavais proposer ci dessus:
XmlLogLine ligne = (XmlLogLine) it.next();
DefaultMutableTreeNode parent=null;
if(!pile.empty()){
parent = (DefaultMutableTreeNode) pile.peek();
}
else return racine;
jarrive a compiler et il me cree bien larbre mais il semblerait que larbre ne soit pas complet ..bizarre bizarre.....pourtant le fichier de donnees contiens 17Mo de donnees..
De plus je reponds a une de tes questions pose en commentaire dans le code: il ny a pas forcement autant de start que de stop car le fichier log est remplie par une application qui met un start quand elle entre dans une methode et stop quand elle al quitte mais si il y a une erreur dans cette (si un bug....si elle se termine pas correctement) alors le stop nest pas ecrit dans le fichier log.....donc pas forcement autant de start que de stop.........
je ne sais pas si jetais clair....
voici larbre en sortie
mince je ne sais pas comment on insere une image
[img][/img]
Marsh Posté le 10-05-2006 à 16:30:23
Citation : il ny a pas forcement autant de start que de stop car le fichier log est remplie par une application qui met un start quand elle entre dans une methode et stop quand elle al quitte mais si il y a une erreur dans cette (si un bug....si elle se termine pas correctement) alors le stop nest pas ecrit dans le fichier log..... |
Ca va être le bordel car du coup quand tu rencontres un stop rien ne te garanti qu'il concerne l'élément que tu as en sommet de pile (ça peut être le stop d'un de ses ancêtres)...
Marsh Posté le 10-05-2006 à 16:39:21
oui effectivement cest un de ces bordel pas possible....je ny peux rien en fait car on me donne le fichier log ainsi fait.....je nai pas control sur ledition du fichier log...........
du coup lago que tu ma propose ne sait pas si il sagit du noeud precedent ou bien le noeud qui se trouve beaucoup plus haut...
voici ce que javais fait Auparavant mais je pense que lalgo nest pas efficace....cest pour cette raison que je lai mis entre parenthese pour le moment.......
private DefaultMutableTreeNode createNodes(Iterator i,DefaultMutableTreeNode racine) {
DefaultMutableTreeNode noeud = null;
XmlLogLine tmp = null;// new XmlLogLine();
while(i.hasNext()){
tmp = (XmlLogLine)i.next();
racine.setAllowsChildren(true);
noeud = new DefaultMutableTreeNode(tmp.getLog_method());
if(tmp.isStart() && !(tmp.isStartStop())){
//noeud = new DefaultMutableTreeNode(tmp.getLog_method());
racine.add(noeud);
racine=noeud;
//createNodes(i,noeud);
}
else if(tmp.isStop() && !(tmp.isStartStop())){
racine=(DefaultMutableTreeNode)racine.getParent();
}
else if(tmp.isStartStop()){
//noeud = new DefaultMutableTreeNode(tmp.getLog_method());
racine.add(noeud);
}
}
return racine;
}
mais avec celui javais limpression que larbre etait complet (cest juste une impressiom , rien est sur).......mais le seul et tres GROS BEMOL cest la conso en memoire qui est enorme.......
Marsh Posté le 10-05-2006 à 17:08:18
Ton algo et le mien font ont à peu près la même chose (j'ai juste remplacé la récursivité par une utilisation de java.util.Stack)
Le problème est que ça ne marche qu'en ligne droite
Si le programme qui a généré les traces plante pendant un de ses traitement il n'y a pas moyen de savoir quand et jusqu'où il faut remonter dans la chaine des parents...
Hummm je pense à un truc.
- l'algo est prévu pour marcher s'il y a autant de start que de stop
- s'il y a plus de start que de stop ce qu'on devrait avoir c'est : à la fin de la boucle (quand on a consommé tous les élément de la liste) il restte des éléments non "fermé" dans la pile
- or ce qu'on a c'est : on a vidé la pile ... Ce qui me fait penser qu'il y aurait plus de stop que de start !!!
Et là c'est encore plus que le bordel, il va falloir vérifier que les données sont cohérentes. C'est-à-dire qu'il n'y a pas de problème à la génération des traces et/ou leur traitement
Marsh Posté le 10-05-2006 à 17:21:37
justement linterface que je suis en train de faire doit permettre aux developpers (de la boite ou je fais mon stage) de savoir dans quelle partie du code, dans quelle classe, dans quelle methode...il y a eu le bug afin qu'il puisse les corriger.
donc apres discussion avec eux, on sest mis daccord sur un arbre representant tous les appels........comme ca il peuvent savoir quelle fonction ne sest pas termine correctement......
je suis pas dans le caca, moi.......
Marsh Posté le 10-05-2006 à 17:44:34
tu sais qu'y'a de bons debuggers et autres profilers, pour tout ça?
Marsh Posté le 10-05-2006 à 17:50:56
oui je leur ai proposer pleins doutils de profilers (une liste toute entiere que je me suis tappe a cherche et a tester) et de plug in ........mais ils ne voulaient pas modifier leur application existante.....il ne voulait pa toucher a laaplication existante...
donc je suis en train de faire mon propre truc.....
et il ny avait pas doutils non plus qui acceptait en entree un fichier log et en sortie des call graph et des call trees........
donc au final je suis la dessus.....jai bien choisi mon stage moi...lol
Marsh Posté le 05-05-2006 à 13:11:24
salut,
suite a mon probleme sur les arbres JTree que jai reussi a resoudre grace a vos aides.....je me retrouve avec un autre probleme.
Donc lorsque je cree mon arbre avec des donnees qui sont dans un fichier *.obj (faisant 5Mo) mon arbre se construisait asses rapidement.
Mais malheureusement quand j'essaie de faire la meme chose avec un fichier *.obj qui fait 30Mo la machine virtuelle de java me dit [#ff0000 size=2]
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space[/#ff0000 size=2]
Donc jai essayer d'allouer plus de memoire a la VM Java avec la commande -Xmx128m mais ca ne suffit toujours pas......
Quelqu'un pourrait maider s'il vous plait?
merci