【问题标题】:AudioInputStream.close() not releasing resources properly, is there a workaround?AudioInputStream.close() 没有正确释放资源,有解决方法吗?
【发布时间】:2014-12-19 17:57:50
【问题描述】:

这是关于我观察到的一个场景的问题:有什么方法可以有效地关闭由我无法查看和控制的 Java 库(如 AudioSystems.getAudioInputStream)打开的系统资源?

那么看看我下面的代码sn-p:

public static void main(String[] args) throws UnsupportedAudioFileException, IOException {
    System.out.println("Before everthing starts...Number of open fd: " + ((UnixOperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean()).getOpenFileDescriptorCount());
    AudioInputStream stream = AudioSystem.getAudioInputStream(new File("CaptchaResource/silence20ms.wav"));
    System.out.println("After reading in one AudioInputStream...Number of open fd: " + ((UnixOperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean()).getOpenFileDescriptorCount());
    stream.close();
    System.out.println("After closing the AudioInputStream...Number of open fd: " + ((UnixOperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean()).getOpenFileDescriptorCount());
    stream = AudioSystem.getAudioInputStream(new File("CaptchaResource/silence20ms.wav"));
    System.out.println("After reading in one AudioInputStream...Number of open fd: " + ((UnixOperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean()).getOpenFileDescriptorCount());
    stream.close();
    System.out.println("After closing the AudioInputStream...Number of open fd: " + ((UnixOperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean()).getOpenFileDescriptorCount())
    stream = AudioSystem.getAudioInputStream(new File("CaptchaResource/silence20ms.wav"));
    System.out.println("After reading in one AudioInputStream...Number of open fd: " + ((UnixOperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean()).getOpenFileDescriptorCount());
    stream.close();
    System.out.println("After closing the AudioInputStream...Number of open fd: " + ((UnixOperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean()).getOpenFileDescriptorCount());
}

如您所见,我使用以下行来打印程序运行时打开的文件描述符的数量:

System.out.println("Number of open fd: " + ((UnixOperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean()).getOpenFileDescriptorCount());

这是我观察到的输出:

Before everthing starts...Number of open fd: 4
After reading in one AudioInputStream...Number of open fd: 44
After closing the AudioInputStream...Number of open fd: 43
After reading in one AudioInputStream...Number of open fd: 45
After closing the AudioInputStream...Number of open fd: 44
After reading in one AudioInputStream...Number of open fd: 46
After closing the AudioInputStream...Number of open fd: 45

您可以看到,除了第一次从 4 跳转到 44 之外,每次我调用 getAudioInputStream 时,我都会打开另外两个文件描述符。当我在流上调用 close() 时,我只能关闭一个。

所以当我的程序必须连续多次处理这个操作时,我最终会达到 Unix 系统中 1024 个打开文件描述符的限制。

通过查看getAudioInputStream的source code,我不确定这是否与由于可能存在多个提供者而在此方法中打开了多个阅读器有关,不太确定那里的实现细节。

这听起来像是 JDK 中已报告的错误,见于:https://bugs.openjdk.java.net/browse/JDK-8013586

有什么解决方法吗?如何重写代码,避免这种不可控的事情发生?

【问题讨论】:

    标签: java audio inputstream ioexception


    【解决方案1】:

    好吧,我不知道其他人是否有更好的方法来做到这一点。我现在将自己回答这个问题,因为这是我要使用的解决方法: 在方法结束时调用 System.gc()。

    不是世界上最伟大的事情。

    【讨论】:

      【解决方案2】:

      旧线程,但如果您从BufferedInputStream 创建AudioInputStream,则不会出现此问题。

      也就是说,这是可行的:

      FileInputStream fis=new FileInputStream(new File(filePath));
      BufferedInputStream bis=new BufferedInputStream(fis);
      AudioInputStream stream=AudioSystem.getAudioInputStream(bis);
      /*
      Some Code
      */
      stream.close();
      bis.close();
      fis.close();
      

      当然,你应该这样做是没有意义的,但它对我有用。

      编辑:澄清一下,这使我能够修改以前不起作用的 filePath 指示的文件(即删除、重命名等)。这可能无法正确完全关闭 AudioInputStream(我的一些测试似乎另有说明)

      【讨论】:

      • 您能否使用此解决方案显示 OPs 测试的输出?
      • 无法使用 OPs 代码进行测试,因为我不在 Unix 中,但我认为这可能无法完全解决问题。我能做的是修改我需要的文件(删除、移动等)。一些测试似乎表明,在关闭流之后,我仍然可以从 AudioInputStream 中获取帧数,​​这可能表明这并不完全有效。但是,在关闭后尝试从文件中读取后,我确实收到了流关闭错误。以防万一人们遇到与我类似的问题。让我知道这是否是现在不合适的解决方案。
      猜你喜欢
      • 2013-04-02
      • 1970-01-01
      • 1970-01-01
      • 2022-10-18
      • 2016-02-03
      • 1970-01-01
      • 2014-02-08
      • 2012-07-09
      • 2016-02-01
      相关资源
      最近更新 更多