尝试使用clip.open()打开174KB的声音文件时出现OutOfMemoryError



我只是试图使用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一起提供)之类的工具。这将显示堆中保留了哪些数据。

最新更新