我只是试图使用javax.sound. samples库播放声音剪辑,使用我在文档中找到的最基本的示例。我见过几十个这样编码的例子,它们似乎都工作,文件只有174KB,所以它不像我试图播放整个音乐会:
public static void main(String[] args) throws UnsupportedAudioFileException, IOException, LineUnavailableException {
// TODO Auto-generated method stub
Clip clip;
AudioInputStream sound = AudioSystem.getAudioInputStream(new File("test.wav"));
AudioFormat format = sound.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, format);
clip = (Clip)AudioSystem.getLine(info);
clip.open(sound);
clip.start();
}
…这会产生错误:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.sun.media.sound.DirectAudioDevice$DirectClip.open(DirectAudioDevice.java:1131)
at test.main(test.java:21)
我真的不知道是什么导致了这个问题,我试过增加JVM的内存限制,但根本没有帮助。
我刚刚查看了异常起源的来源,在这个方法中,它试图分配一个大小为
的字节缓冲区 audioInputStream.getFrameLength() * audioInputStream.getFormat().getFrameSize()
如果audioInputStream.getFrameLength()
返回除-1以外的任何值。因此,您的媒体文件可能会为这些参数中的任何一个返回不寻常的值,从而导致此代码尝试分配一个非常大的内存块。我建议检查一下你为wav文件计算的值,如下所示:
AudioInputStream sound = AudioSystem.getAudioInputStream(new File("test.wav"));
System.out.println( "frame length: " + sound.getFrameLength() );
System.out.println( "frame size: " + sound.getFormat().getFrameSize() );
将以下内容添加到Java命令
-XX:+HeapDumpOnOutOfMemory
并且在获得OOM之后,JVM将生成一个二进制堆转储,您可以使用Eclipse MAT或VisualVM(随JDK一起提供)之类的工具。这将显示堆中保留了哪些数据。