使用java播放声音时内存泄漏

时间:2014-04-23 13:34:24

标签: java audio memory-leaks

这是我播放声音的代码:

public class Sound {
    public static void playSound(String path)
    {
      try 
      {
           Clip clip = AudioSystem.getClip();
           AudioInputStream inputStream = AudioSystem.getAudioInputStream(new File(path));
           clip.open(inputStream);
           inputStream.close();
           clip.start(); 
        } catch (Exception e) {
           e.printStackTrace();
        }               
    }
}

如果我调用Sound.playSound(“xxx.wav”);很多时候,我看到根据任务经理的说法,我的公羊开始急剧上升。我该如何清理它?

3 个答案:

答案 0 :(得分:1)

尝试关闭方法。来自JavaDOC:

  

void close()关闭该行,指示所有系统资源   线路使用可以释放。如果此操作成功,则行   标记为已关闭,并将CLOSE事件发送到该行   听众。

答案 1 :(得分:1)

编写剪辑的方式(包括播放加载)表明SourceDataLine效率更高。在播放剪辑的同时加载剪辑会产生大量不必要的延迟。在文件将完全加载到RAM中之前,Clip不会开始播放,而SourceDataLine将立即开始(一旦开始接收文件数据)。

剪辑应该通过open()加载一次。打开后,数据就位于RAM中,随时可用。剪辑被设计用于多个播放,具有尽可能低的延迟。但是只有将负载与播放分开才能实现低延迟,并且只是在已经加载的剪辑上调用播放。

内存分配的增加可能是由于所有Clips继续重新加载到RAM中。 (每次调用都会在RAM中创建一个额外的实例,而音频文件并不便宜。)如果重放一个Clip,只需加载一次并重复使用多次start()调用。

使用SourceDataLine是另一种选择。它不会将整个声音文件加载到RAM中,而是从文件位置传输它。但是当你完成时,请确保并关闭它,因为未封闭的数据行或文件流可能是内存泄漏的另一个来源。

答案 2 :(得分:0)

首先,正如其他人建议的那样 - 在close()上使用Clip clip方法。也关闭inputStream(就像你现在一样)。

另一件事是Java管理内存本身(通过JVM - Java虚拟机)。例如。对象在它们变得过时的地方被清除(即超出范围,没有引用)。它与C ++不同,你必须分配和释放内存。

但在Java中,#34; deallocation"发生在使用Garbage Collector(网上有很多参考资料)。 JVM调用GC,很难准确判断何时。

所以我们在这里看到的是Java将一些资源加载到内存中(以对象方式处理它)。它们每个都耗尽你的系统内存。使用后不会立即清除内存。一旦JVM调用GC,它将被清除。它并不意味着你有内存泄漏。

两个提示:

  • 如果系统内存不足,JVM会调用GC,因此您不必担心没有资源(除非您在同一时间内使用大量资源)。
  • 你可以手动"问" GC使用Java代码执行操作:System.gc()但不保证它会立即执行。

修改 要确认这一点,请尝试手动调用gc(System.gc())并查看它是否释放内存,但是您不应该在最终解决方案中使用它。