这是我播放声音的代码:
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”);很多时候,我看到根据任务经理的说法,我的公羊开始急剧上升。我该如何清理它?
答案 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,它将被清除。它并不意味着你有内存泄漏。
两个提示:
System.gc()
但不保证它会立即执行。修改强> 要确认这一点,请尝试手动调用gc(System.gc())并查看它是否释放内存,但是您不应该在最终解决方案中使用它。