2014-10-23 1 views
1

이것은 내가 관찰 한 시나리오와 관련하여 질문입니다. 가시성 및 제어 권한이없는 AudioSystems.getAudioInputStream과 같은 Java 라이브러리에서 시스템 리소스를 효과적으로 닫는 방법은 무엇입니까?AudioInputStream.close()가 자원을 제대로 해제하지 못하는 경우 해결 방법이 있습니까?

그래서 내 다음 코드에서 살펴 :

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

이 거기에 대안인가? 어떻게 제어 할 수없는 일이 발생하지 않도록 코드를 다시 작성할 수 있습니까?

답변

2

좋아 다른 사람이이 작업을 수행하는 데 더 좋은 방법이 있는지 알 수 없습니다. 이 방법은 제가 사용하려고하는 해결 방법이므로 지금 당장 답할 것입니다 : 메서드의 끝에서 System.gc()를 호출하십시오.

세계에서 가장 위대한 것은 아닙니다.

0

오래된 스레드 있지만 BufferedInputStreamAudioInputStream 만드는 경우이 문제가 발생하지 않습니다.

물론
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을 올바르게 닫지 못할 수도 있습니다 (일부 테스트에서 다른 부분을 나타내는 것 같습니다)

+1

이 솔루션을 사용하여 OPs 테스트 결과를 표시 할 수 있습니까? –

+0

유닉스에 없기 때문에 OP 코드를 사용하여 테스트 할 수는 없지만 이것이 문제를 완전히 해결하지는 못했다고 생각합니다. 내가 할 수 있었던 것은 필자가 필요로하는 파일 (삭제, 이동 등)을 수정하는 것이 었습니다. 어떤 테스트는 아마도 스트림을 닫은 후에 AudioInputStream에서 프레임 카운트를 얻을 수 있음을 나타냅니다. 아마 이것이 완전하게 작동하지 않는다는 것을 나타낼 수 있습니다. 그러나 닫은 후 파일에서 읽으려고 시도한 후에 스트림을 닫은 오류가 발생했습니다. 사람들이 내가 가지고있는 것과 비슷한 이슈를 가지고있는 경우를 지킨다.이것이 지금 부적절한 해결책인지 알려주십시오. – BinaryPill

관련 문제