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

Java ME Discussion :

OutOfMemoryError sur timer


Sujet :

Java ME

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 6
    Par défaut OutOfMemoryError sur timer
    Bonjour à tous,

    Je sollicite votre aide pour un problème de débordement mémoire.

    Le programme doit mettre en route un chrono (timer) lorsque l'on appuis sur ok (après avoir rentrer les configurations de base) et doit s'arrêter dans une explosion formidable qu'elle est bien :-) si personne n'appuis à nouveau sur ok. Dans le cas contraire, le chrono doit s'arrêter, être remis à la valeur donnée pendant la configuration, et attendre qu'on déclenche à nouveau le timer.

    Tout ce petit monde marche très bien, à un détails prêt (de taille quand même !) :
    TRACE: <at java.lang.OutOfMemoryError>, Exception caught in Display class
    java.lang.OutOfMemoryError (stack trace incomplete)

    Ne sachant pas où se situe l'erreur (même si je penche pour des processus zombies, vous m'en direz plus...), je me suis dis que j'allais explicitement appeler le garbage collector. Ceci n'a rien changé...

    Comme ce programme ne révolutionnera pas le monde, je le mets entier ici.

    Je vous remercie par avance de toute l'aide que vous m'apporterez.

    Cordialement, Alexaptor

    PS : le deuxième timer pour la durée de la partie n'est pas encore intégré. En attendant vos réponses, je me penche sur ce problème.

    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
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
     // le code de la classe main
     
    package bomb;
     
    import javax.microedition.midlet.*;
    import javax.microedition.lcdui.*;
    import javax.microedition.media.*;
    import java.util.Timer;
    import java.io.*;
     
    public class Main extends MIDlet implements CommandListener {
     
        protected Command exitCommand, ok; // The exit command
        protected Display display;     // The display for this MIDlet
        private Timer timer;
        protected int initialCounter, counter, gameDuration;
        private TextField delay, duration;
        private Form form;
        private boolean state;
     
        public Main() {
     
            this.counter = 0;
            this.gameDuration = 0;
            this.state = false; // test pour savoir si le timer est en route ou coupé
     
            display = Display.getDisplay(this);
            exitCommand = new Command("Exit", Command.EXIT, 0);
            ok = new Command("OK", Command.OK, 2);
        }
     
        public void startApp() {
            delay = new TextField("Delais explosion", "", 30, TextField.DECIMAL);
            duration = new TextField("Durée partie", "", 30, TextField.DECIMAL);
            form = new Form("Configurations");
            form.append(delay);
            form.append(duration);
            form.addCommand(ok);
            form.setCommandListener(this);
            display.setCurrent(form); // formulaire des configurations de base
        }
     
        public void pauseApp() {}
        public void destroyApp(boolean unconditional) {}
     
        public void commandAction(Command c, Displayable s) {
            String label = c.getLabel();
            if (c == exitCommand) // fermeture programme
            {
                destroyApp(false);
                notifyDestroyed();
            }
            else if(label.equals("OK")) // bouton ok enfoncé
            {
                if(this.counter == 0) // le délais n'est pas choisi, initialisation
                {
                    this.counter = Integer.parseInt(this.delay.getString()) + 1;
                    this.initialCounter = this.counter; // on garde un compteur initial
                    this.gameDuration = Integer.parseInt(this.duration.getString());
     
                }
                else
                {
                    if(!this.state) // state ==  true alors ou arrête et vis versa
                        this.startTimer();
                    else
                        this.stopExplosion();
                }
            }
        }
     
        public void armed()
        {
            this.stopTimer(); // on arrête le timer
            form = new Form("Stand By");
            form.addCommand(ok);
            form.setCommandListener(this);
            display.setCurrent(form); // on se remet à l'écoute
        }
     
        public void stopExplosion()
        {
            try
            {
                Player player = Manager.createPlayer(getClass().getResourceAsStream("disarmed.wav"), "audio/x-wav");
                player.start(); // on joue le son "desarmé"
            }
            catch(MediaException e){}
            catch(IOException e){}
     
            this.armed(); // on prépare l'écoute
        }
     
        public void startTimer()
        {
            System.out.println("start counter : "+this.counter+" init : "+this.initialCounter);
     
            this.state = true;
            this.timer = new Timer(); 
    // on lance un timer qui fera une action toutes les secondes
            this.timer.scheduleAtFixedRate(new Explosion(this), 0, 1000);
     
     
        }
     
        public void stopTimer()
        {
            System.out.println("stop counter : "+this.counter+" init : "+this.initialCounter);
     
            this.state = false;
            this.counter = this.initialCounter;
            this.timer.cancel();
            System.gc(); // garbage collector
     
        }
    }

    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
     // le code du timerTask
     
    package bomb;
    import java.util.TimerTask;
    import javax.microedition.lcdui.*;
    import javax.microedition.media.*;
    import java.io.*;
     
    public class Explosion extends TimerTask {
     
        private Main main;
     
        public Explosion(Main main)
        {
            this.main = main;
        }
     
        public void run()
        {
            String text = "";
            String ressource = "";
            this.main.counter--;
     
            if(this.main.counter == 0)
            {
                ressource = "explosionPCMSstereo.wav"; // son pour l'explosion
                text = "BOOOM";
                this.main.stopTimer();
                this.cancel();
            }
    // compte à rebours
            else if(this.main.counter == (this.main.initialCounter - 1)) 
            {
                ressource = "bombpl.wav";
                text = String.valueOf(this.main.counter);
            }
    // pas de son à délais total - 2 secondes pour éviter la coupure du son précédent
            else if(this.main.counter == (this.main.initialCounter - 2))
                text = String.valueOf(this.main.counter);
            else
            {
                if(this.main.counter > 5) // bip normal
                    ressource = "bip1.wav";
                else
                    ressource = "bip2.wav"; // bip d'alerte
                text = String.valueOf(this.main.counter);
            }
     
            if(this.main.counter != (this.main.initialCounter - 2))
            {
                try
                {
                    Player player = Manager.createPlayer(getClass().getResourceAsStream(ressource), "audio/x-wav");
                    player.start(); // lecture du son
                }
                catch(MediaException e){}
                catch(IOException e){}
            }
     
            Form form = new Form("Compte à rebours");
            TextField delay = new TextField("Il reste", text, 30, TextField.UNEDITABLE);
            form.append(delay);
            form.addCommand(this.main.ok);
            form.setCommandListener(this.main);
            this.main.display.setCurrent(form); // affichage à l'écran du nombre de secondes
        }
    }

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 6
    Par défaut Test supplémentaire
    Bonjour,

    j'ai rajouté cette instruction afin d'être sûr pour les processus fils, mais visiblement, ça ne change rien...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
        // dans l'initialisation
        this.explosion = new Explosion(this);
     
        public void stopTimer()
        {
            this.state = false;
            this.counter = this.initialCounter;
            this.explosion.cancel();
            this.explosion = null;
            this.timer.cancel();
            this.timer = null;
            System.gc();
        }
    Personne n'a d'idées ? De propositions ?
    Allez y, n'ayez pas peur :-) !

    Alexaptor

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 476
    Par défaut
    Salut,

    En general tu as outOfMemory soit parce que ta machine virtuelle ne dipose pas d'assez de mémoire pour le fonctionnement normal de l'appli , soit à cause d'un bugs où des objets ou traitement sont réalisés sans fin ou presque.
    La stacktrace complète de ton exception nous aiderait à mieux comprendre ton cas.
    Aussi, indique nous à quelle instruction de ton code correspond la ligne d'origine de la levée de l'exception.

    System.gc();
    J'ai jamais bossé sur du java ME, mais en java SE ou EE, ce n'est généralement jamais une bonne idée. Le gc passe tout seul assez rapidement et l'appel à gc() n'a aucune garantie de le lancer plus rapidement. Si une appli a besoin de plus de mémoire, il faut qu'elle en embarque plus.

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 6
    Par défaut stacktrace tronquée
    Bonjour,

    Merci pour ta réponse.

    Avant toute chose chose, je suis d'accord au sujet de l'appel du garbage. Il doit bien s'agir du premier programme que je fais appel à lui explicitement... Mais quand on cherche une solution... :-)

    Sinon, pour quelque chose qui tourne en boucle, je serais assez d'accord. Se pourrait-il que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
            this.explosion.cancel();
            this.explosion = null;
            this.timer.cancel();
            this.timer = null;
    ne soit pas suffisant pour clore le timer en cours et la tâche ?

    Il est vrai que la stacktrace complète serait un réel plus pour diagnostiquer, le problème, c'est que je n'ai pas d'indications supplémentaires. Le programme tronque de lui même la sortie d'erreur... Aurais tu une instruction toute prête pour faire en sorte qu'il nous la donne complète ?

    Merci

    Alexaptor

  5. #5
    Membre expérimenté

    Avatar de mlny84
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    4 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 4 023
    Par défaut
    Citation Envoyé par alexaptor Voir le message
    Il est vrai que la stacktrace complète serait un réel plus pour diagnostiquer, le problème, c'est que je n'ai pas d'indications supplémentaires. Le programme tronque de lui même la sortie d'erreur... Aurais tu une instruction toute prête pour faire en sorte qu'il nous la donne complète ?
    Bonjour,

    Tu peux rediriger la sortie d'erreur dans un fichier texte pour avoir la stacktrace complète.
    Si tu travailles sous Eclipse, Run Configurations -> Onglet Common -> Cocher File et donner le chemin du fichier.

Discussions similaires

  1. Aide sur Timer
    Par Kemanke dans le forum MFC
    Réponses: 1
    Dernier message: 28/06/2007, 10h10
  2. Une qustion sur timer
    Par gueulederack dans le forum MFC
    Réponses: 2
    Dernier message: 22/05/2007, 15h29
  3. [Formulaire]Lancement de requêtes sur timer
    Par GIPPE dans le forum IHM
    Réponses: 2
    Dernier message: 12/04/2007, 20h57
  4. [C#] ptite question sur timer
    Par moulefrite dans le forum Windows Forms
    Réponses: 5
    Dernier message: 06/06/2006, 10h24
  5. Petite question sur timer
    Par nou366 dans le forum Delphi
    Réponses: 2
    Dernier message: 12/05/2006, 18h50

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