2010-05-08 3 views
1

avoir une application qui traite les données en temps réel et est censée émettre un bip lorsqu'un certain événement se produit. L'événement déclencheur peut se produire plusieurs fois par seconde, et si le bip est déjà en cours de lecture lorsqu'un autre événement se déclenche, le code est simplement censé l'ignorer (au lieu d'interrompre le bip actuel et d'en commencer un nouveau). Voici le code de base:dois-je fermer un clip audio?

Clip clickClip 

public void prepareProcess() { 
    super.prepareProcess(); 

    clickClip = null; 

    try { 
     clipFile = new File("C:/WINDOWS/Media/CHIMES.wav"); 
     ais = AudioSystem.getAudioInputStream(clipFile); 
     clickClip = AudioSystem.getClip(); 
     clickClip.open(ais); 

     fileIsLoaded = true; 

    } catch (Exception ex) { 
     clickClip = null; 
     fileIsLoaded = false; 
    } 
} 

public void playSound() { 

    if (fileIsLoaded) { 

     if ((clickClip==null) || (!clickClip.isRunning())) { 

      try { 
       clickClip.setFramePosition(0); 
       clickClip.start(); 
      } catch (Exception ex) { 
       System.out.println("Cannot play click noise"); 
       ex.printStackTrace(); 
      } 
     } 
    } 

La méthode prepareProcess s'exécuter une fois le début et la méthode de playSound est appelé à chaque fois qu'un événement déclencheur se produit. Ma question est: dois-je fermer l'objet clickClip? Je sais que je pourrais ajouter une actionListener pour surveiller un événement Stop, mais comme l'événement se produit si souvent, je crains que le traitement supplémentaire ne ralentisse la collecte de données en temps réel.

Le code semble fonctionner correctement, mais mon inquiétude concerne les fuites de mémoire. Le code ci-dessus est basé sur un exemple que j'ai trouvé lors de la recherche sur le net, mais l'exemple utilisait un actionListener pour fermer le clip spécifiquement "pour éliminer les fuites de mémoire qui se produiraient lorsque la méthode stop n'était pas implémentée". Mon programme est destiné à fonctionner pendant des heures afin que toute fuite de mémoire que j'ai aura des problèmes.

Je vais être honnête: je ne sais pas comment vérifier si j'ai un problème ou non. J'utilise Netbeans, et l'exécution du profileur de mémoire m'a juste donné une énorme liste de choses que je ne sais pas lire. C'est supposé être la partie simple du programme, et je passe des heures dessus. Toute aide serait grandement appréciée!

Michael

Répondre

0

fuites de mémoire en Java doivent faire avec des objets qui sont encore référencés, même après leur durée de vie ont pris fin. Dans de nombreux cas, cela sera dû à quelque chose comme faire 50 objets à plusieurs reprises, mais en éliminant seulement les références à 49 d'entre eux plus tard.

Rien de tel ne semble se produire dans votre code. Depuis prepareProcess() ne fonctionne qu'une seule fois, ce n'est pas très suspect. Cela laisse playSound(), qui ne contient aucune instanciation d'objet, et encore moins une boucle d'élimination de référence défectueuse. L'inconvénient est que je ne suis pas sûr de ce qui se passe dans les coulisses de votre objet clip audio, et il est difficile de vérifier car majuscule-C Clip est seulement une interface. Sauf si vous utilisez du code tiers, je serais très surpris d'y trouver une fuite.

Longue histoire courte, Je ne m'inquiéterais pas à moins et jusqu'à ce que vous voyez réellement quelque chose comme OutOfMemoryError.

+0

Merci beaucoup pour la réponse. Je suis d'accord avec vous pour dire que, selon le code que je donne, cela ne semble pas poser de problème. Mais (comme vous le mentionnez) je ne sais pas non plus ce qui se passe dans les coulisses de l'objet Clip.Fooling autour de plus avec le profileur de mémoire Netbeans, il semble qu'un nouvel objet est attribué chaque fois que le son est joué. Cependant, la colonne Live Object n'augmente jamais, donc je suppose que cela signifie que la garbage collection s'en occupe immédiatement. Comportement étrange, mais je ferai en sorte de le regarder pendant les tests pour m'assurer que tout va bien. Merci encore. Michael – Michael

4

oui, la fermeture est nécessaire

myClip.addLineListener(new LineListener() { 
    public void update(LineEvent myLineEvent) { 
     if (myLineEvent.getType() == LineEvent.Type.STOP) 
     myClip.close(); 
    } 
    }); 

ou par

if (!myClip.isRunning()) 
    myClip.close(); 

Dans ma demande (écrite avant l'avènement de util.concurrent), c'est le mécanisme de fermeture du clip.

public static final Vector<Clip> vector = new Vector<Clip>(); 
    static final int vector_size = 5; 

    // typically called before calling play() 
    static synchronized void consolidate() { 
    while (vector_size < vector.size()) { 
     Clip myClip = vector.get(0); 
     if (myClip.isRunning()) 
     break; 
     myClip.close(); 
     vector.remove(0); 
    } 
    if (vector_size * 2 < vector.size()) 
     System.out.println("warning: audio consolidation lagging"); 
    } 

    public static void play(final File myFile) { 
    try { 
     AudioInputStream myAudioInputStream = AudioSystem.getAudioInputStream(myFile); 
     final Clip myClip = AudioSystem.getClip(); 
     vector.add(myClip); 
     myClip.open(myAudioInputStream); 
     myClip.start(); 
    } catch (Exception myException) { 
     myException.printStackTrace(); 
    } 
    } 

Comme l'un des commentaires suggèrent, il peut retarder la lecture de nouveaux clips, mais je ne me souviens que quelques retards ms ne sont pas importants dans ma demande.

+1

Quelle est la justification de votre réponse? pourquoi est-ce nécessaire? Quels sont les bénéfices? – pstanton

+0

Si vous ne fermez pas les clips, tout ira bien, jusqu'à ce que votre programme se bloque à cause d'un goulot d'étranglement. C'est l'application où j'ai rencontré ce problème: [link] (http://www.youtube.com/watch?v=3F06TdnnOjQ) – datahaki

+0

intéressant. J'ai trouvé que la fermeture des clips était trop chère et quand cela est fait alors que la lecture est active (en utilisant un autre clip), cela provoque des retards. Je vais devoir tester la théorie sur la collecte des ordures, et éventuellement fermer les clips en masse lorsque toute la lecture audio est inactive peut-être. avez-vous remarqué les retards lors de la fermeture et comment avez-vous surmonté cela? – pstanton

Questions connexes