我需要关闭音频片段吗?

有一个处理实时数据的应用程序,并且当某个事件发生时应该发出蜂鸣声。 触发事件可以每秒发生多次,并且如果在另一个事件触发时蜂鸣声已经播放,则代码应该忽略它(而不是中断当前的蜂鸣声并开始新的蜂鸣声)。 这是基本代码:

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(); } } } 

prepareProcess方法在开始时运行一次,每次发生触发事件时都会调用pl​​aySound方法。 我的问题是:我需要关闭clickClip对象吗? 我知道我可以添加一个actionListener来监视Stop事件,但由于事件经常发生,我担心额外的处理会减慢实时数据收集速度。

代码似乎运行良好,但我担心的是内存泄漏。 上面的代码基于我在搜索网络时发现的示例,但该示例使用了actionListener来专门关闭Clip“以消除在未实现stop方法时可能发生的内存泄漏”。 我的程序打算运行几个小时,所以任何内存泄漏都会导致问题。

老实说:我不知道如何validation我是否有问题。 我正在使用Netbeans,运行内存分析器只是给了我一大堆我不知道如何阅读的内容。 这应该是该计划的简单部分,我花了几个小时。 任何帮助将不胜感激!

迈克尔

是的,关闭是必要的

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

或者

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

在我的应用程序(在util.concurrent出现之前编写)中,这是剪辑关闭机制。

  public static final Vector vector = new Vector(); 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(); } } 

正如其中一条评论所暗示的那样,它可能会延迟新剪辑的播放,但我不记得因为几毫秒的延迟在我的应用程序中并不重要。

Java中的内存泄漏与即使在它们的使用寿命结束后仍然被引用的对象有关。 在许多情况下,这将是由于重复制作50个对象之类的东西,但后来仅消除对其中49个对象的引用。

在你的代码中似乎没有这样的东西。 由于prepareProcess()只运行一次,因此不是很可疑。 这就离开了playSound() ,它根本不包含任何对象实例化,更不用说错误的引用消除循环了。

需要注意的是,我不确定你的声音剪辑对象幕后发生了什么,而且很难检查,因为majuscule-C Clip只是一个界面。 但是,除非您使用第三方代码,否则我会非常惊讶地发现泄漏。

长话短说, 我不会担心,除非你真的看到类似OutOfMemoryError东西。