使用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