2013-05-20 3 views
1

Aujourd'hui, j'ai ouvert le Gestionnaire des tâches et j'ai vu que mon application perdait 200 Ko de mémoire par seconde. J'ai regardé ma boucle principale:JFrame fuite de mémoire?

public final void run() { 
    try { 
     Thread.sleep(27); 
    } catch (InterruptedException e1) { 
     e1.printStackTrace(); 
    } 

    Thread curThread = Thread.currentThread(); 
    long lastLoopTime = System.nanoTime(); 
    long OPTIMAL_TIME = 1000000000/FPS; 
    int fps = 0; 
    long lastFpsTime = 0; 

    while (thread == curThread) { 
     if (shouldClose) 
     { 
      running = false; 
      frame.dispose(); 
      thread = null; 
      curThread.interrupt(); 
      curThread = null; 
     } 

     long now = System.nanoTime(); 
     long updateLength = now - lastLoopTime; 
     lastLoopTime = now; 
     //double delta = updateLength/((double)OPTIMAL_TIME); 

     lastFpsTime += updateLength; 
     fps++; 

     if (lastFpsTime >= 1000000000) { 
      System.out.println("FPS: " + fps + ""); 
      fpsLabel.setText("FPS: " + fps); 
      lastFpsTime = 0; 
      fps = 0; 
     } 

     if (GuiNewProject.createButton.isEnabled() && createProjectDialogIsOpen) 
      if (GuiNewProject.folder.getText().length() == 0 || GuiNewProject.projectName.getText().length() == 0) 
       GuiNewProject.createButton.setEnabled(false); 

     if (!(GuiNewProject.createButton.isEnabled()) && createProjectDialogIsOpen) 
      if (GuiNewProject.folder.getText().length() > 0 && GuiNewProject.projectName.getText().length() > 0) 
       GuiNewProject.createButton.setEnabled(true); 

     //render(); 
     fpsDone.setText("FPS: " + fps); 

     try { 
      if (shouldClose) { 
       return; 
      } 
      else 
      { 
       Thread.sleep((lastLoopTime - System.nanoTime() + OPTIMAL_TIME)/1000000); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    SwingUtilities.invokeLater(this); 
} 

Et je n'arrive pas à comprendre pourquoi cela continue de fuir la mémoire? Toute indication ou solution à cette fuite de mémoire serait utile!

Cordialement, tambre

+0

S'il vous plaît créer un [SSCCE] (http://www.sscce.org) qui démontre le problème et met à jour votre question. –

+0

n'est pas possible à partir de code_snipped posté ici, pour une meilleure aide plus tôt post un SSCCE, court, runnable, compilable – mKorbel

+0

FYI tout invoqué depuis invokeLater & killed par Thread.sleep (int) reste dans la mémoire JVM jusqu'à Thread.sleep (int) terminé – mKorbel

Répondre

2

JLabel.setText() appelle repaint, qui pousse un PaintEvent dans la file d'attente d'événements. Parce que votre boucle bloque la file d'attente des événements, elle se développe indéfiniment. D'où la fuite de mémoire.

(SwingUtilities.invokeLater() exécute un Runnable sur le EDT. Si ce runnable ne retourne jamais, comme le vôtre ici, alors ne peut traiter d'autres événements)

2

Regardez cette partie du programme:

while (thread == curThread) { 
    if (shouldClose) 
    { 
     running = false; 
     frame.dispose(); 
     thread = null; 
     curThread.interrupt(); 
     curThread = null; 
     // HERE 
    } 
    // ... 
} 

Question: Qu'est-ce qui thread == curThread être au point où je Labellisé "ICI"?

Réponse: Vrai.

Question: Et la boucle se terminera-t-elle?

Réponse: Non!


Pour être brutalement honnête, cette partie de votre code est un gâchis. Vous semblez utiliser deux ou trois mécanismes différents pour tenter de tuer ... quelque chose. Enfin, vous appelez le SwingUtilities.invokeLater(this) qui (je pense) lancera un autre thread pour relancer le Runnable. C'est juste ... incompréhensible.

+0

Donc, je devrais dire pour enlever curThread = null ;? – tambre

+0

@tambre - Je pense que vous devriez probablement jeter toute la méthode et recommencer! –

+0

La boucle * va * se terminer, car plus tard elle aura 'if (shouldClose) return; –

1

Après commething ces lignes:

fpsLabel.setText("FPS: " + fps); 
fpsDone.setText("FPS: " + fps); 

Les fuites de mémoire semble être branché. Pourquoi setText() fuit-il de la mémoire? Question est un peu répondu, mais encore pourquoi?