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

使用java播放声音时内存泄漏,java,audio,memory-leaks,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));

这是我播放声音的代码:

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”);很多时候,我看到我的ram根据任务管理器开始急剧上升。我如何清理它?

试试关闭方法。从JavaDOC:

void close()关闭该行,表示 可通过线路释放使用。如果此操作成功,则该行 标记为关闭,并将关闭事件发送到线路的 听众


首先,正如其他人所建议的,在
Clip-Clip
上使用
close()
方法。同时关闭
inputStream
(就像您现在所做的那样)

另一件事是Java管理内存本身(通过JVM-Java虚拟机)。例如,对象在过时时被清除(即超出范围,无参考)。它与C++不同,在这里你必须分配和释放内存。 但是在Java中,“释放”是通过
垃圾收集器来实现的(web上有很多引用)。GC是由JVM调用的,很难准确判断何时调用

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

两个提示:

  • JVM在系统内存不足的情况下调用GC,因此您不应该担心没有资源(除非您同时使用大量资源)
  • 您可以使用Java代码手动“请求”GC执行操作:
    System.GC()
    ,但不能保证它会立即执行
编辑:
要确认这一点,请尝试手动调用gc(System.gc())并查看它是否释放内存,但您不应该在最终解决方案中使用它。

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

剪辑应通过open()加载一次。一旦打开,数据就保存在RAM中,随时可以使用。剪辑是为多个播放设计的,具有尽可能低的延迟。但是,只有将加载与播放分离,并且仅在已加载的剪辑上调用播放,才能实现低延迟

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


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

好吧,如果你打开一条小溪,你不觉得你也应该把它关上吗?:)我想说你需要关闭剪辑-
clip.close()
好的,我会关闭流,但是我如何在正确的时间关闭剪辑?我如何知道声音何时结束,以及如果我同时播放了多个片段,如何引用特定片段1。
Clip
界面中没有
close()
方法。2.关闭输入流有帮助吗?3.您是一次运行多次还是一次又一次运行?@Fazovsky方法继承自javax.sound.sampled.Line接口:addLineListener、close、getControl、getControls、getLineInfo、isControlSupported、isOpen、open、removeLineListener