2010-05-08 3 views
1

에는 실시간 데이터를 처리하는 응용 프로그램이 있으며 특정 이벤트가 발생할 때 신호음이 울리기로되어 있습니다. 트리거링 이벤트는 초당 여러 번 발생할 수 있으며, 다른 이벤트가 트리거 될 때 경고음이 이미 재생 중이면 코드를 무시해야합니다 (현재 경고음을 중단하고 새 경고음을 시작하는 것과 반대).오디오 클립을 닫아야합니까?

Clip clickClip 

public void prepareProcess() { 
    super.prepareProcess(); 

    clickClip = null; 

    try { 
     clipFile = new File("C:/WINDOWS/Media/CHIMES.wav"); 
     ais = AudioSystem.getAudioInputStream(clipFile); 
     clickClip = AudioSystem.getClip(); 
     clickClip.open(ais); 

     fileIsLoaded = true; 

    } catch (Exception ex) { 
     clickClip = null; 
     fileIsLoaded = false; 
    } 
} 

public void playSound() { 

    if (fileIsLoaded) { 

     if ((clickClip==null) || (!clickClip.isRunning())) { 

      try { 
       clickClip.setFramePosition(0); 
       clickClip.start(); 
      } catch (Exception ex) { 
       System.out.println("Cannot play click noise"); 
       ex.printStackTrace(); 
      } 
     } 
    } 

prepareProcess 방법은 처음에 한 번만 실행됩니다, 그리고 꺼내, 방법은 트리거 이벤트가 발생할 때마다 호출됩니다 여기에 기본 코드입니다. 내 질문은 : clickClip 개체를 닫아야합니까? Stop 이벤트를 모니터링하기 위해 actionListener를 추가 할 수 있다는 것을 알고 있지만, 이벤트가 자주 발생하므로 추가 처리가 실시간 데이터 수집 속도를 늦추 게 될까봐 걱정됩니다.

코드가 정상적으로 실행되는 것으로 보이지만 내 걱정은 메모리 누수입니다. 위의 코드는 그물을 검색하는 동안 찾은 예제를 기반으로하지만이 예제에서는 "stop 메서드가 구현되지 않은 경우 발생할 메모리 누수를 없애기 위해"Clip을 구체적으로 닫는 데 actionListener를 사용했습니다. 내 프로그램은 몇 시간 동안 실행되도록 설계되어있어 내가 가진 모든 메모리 누수로 인해 문제가 발생합니다.

솔직히 말해서 : 나는 문제가 있는지 여부를 확인하는 방법을 모른다. Netbeans를 사용하고 있으며 메모리 프로파일 러를 실행하면 읽는 법을 모르는 거대한 목록을 얻을 수있었습니다. 이것은 프로그램의 단순한 부분이라고 생각되며, 나는 그것에 시간을 보내고 있습니다. 어떤 도움이라도 대단히 감사하겠습니다! 자바

마이클

답변

0

메모리 누수는 여전히 연수가 끝난 후에도 참조되고있는 객체를해야한다. 많은 경우에, 이것은 반복적으로 50 개의 물체를 만드는 것과 같은 것일 것이지만 나중에 49 개의 물체에 대한 참조만을 제거 할 것이기 때문입니다.

코드에서 아무 것도 일어나지 않는 것 같습니다. prepareProcess()은 한 번만 실행되기 때문에 의심의 여지가 없습니다. 즉, 객체 인스턴스화가 전혀 포함되지 않은 playSound()이 나오고 잘못된 참조 제거 루프가 발생하지 않습니다.

소리 클립 객체의 장면 뒤에서 무슨 일이 일어나는지 잘 모르겠다. majuscule-C Clip은 인터페이스 일 뿐이므로 확인하기가 어렵다. 제 3 자 코드를 사용하지 않는다면, 거기에 누수가 있다는 사실을 알고 놀랄 것입니다.

길게 짧음, 너는 실제로 OutOfMemoryError과 같은 것을 볼 때까지 나는 그것에 대해 걱정하지 않을 것이다.

+0

답변 해 주셔서 감사합니다. 나는 당신이 동의하는 코드에 기초하여 문제가되지 않는다고 동의한다. 그러나 (당신이 언급했듯이) 나는 Clip 객체의 장면 뒤에서 어떤 일이 일어나고 있는지 모른다.Netbeans 메모리 프로파일 러를 사용하면 사운드가 재생 될 때마다 새로운 객체가 할당 된 것처럼 보입니다. 그러나 Live Object 열은 결코 증가하지 않으므로 가비지 콜렉션이 즉시이를 처리한다는 것을 전제로합니다. 이상한 행동이지만, 테스트를하는 동안 그것을 지켜서 확인하는 것이 좋습니다. 다시 한 번 감사드립니다. 마이클 – Michael

4

네, 폐쇄

myClip.addLineListener(new LineListener() { 
    public void update(LineEvent myLineEvent) { 
     if (myLineEvent.getType() == LineEvent.Type.STOP) 
     myClip.close(); 
    } 
    }); 

또는 (util.concurrent의 출현 이전에 작성된) 내 응용 프로그램에서

if (!myClip.isRunning()) 
    myClip.close(); 

에 의해

, 이것은 클립 폐쇄 메커니즘이 필요하다.
public static final Vector<Clip> vector = new Vector<Clip>(); 
    static final int vector_size = 5; 

    // typically called before calling play() 
    static synchronized void consolidate() { 
    while (vector_size < vector.size()) { 
     Clip myClip = vector.get(0); 
     if (myClip.isRunning()) 
     break; 
     myClip.close(); 
     vector.remove(0); 
    } 
    if (vector_size * 2 < vector.size()) 
     System.out.println("warning: audio consolidation lagging"); 
    } 

    public static void play(final File myFile) { 
    try { 
     AudioInputStream myAudioInputStream = AudioSystem.getAudioInputStream(myFile); 
     final Clip myClip = AudioSystem.getClip(); 
     vector.add(myClip); 
     myClip.open(myAudioInputStream); 
     myClip.start(); 
    } catch (Exception myException) { 
     myException.printStackTrace(); 
    } 
    } 

의견 중 하나는 제안으로

, 그것은 새로운 클립의 재생이 지연 될 수 있습니다,하지만 난 몇 밀리 초 지연이 내 응용 프로그램에서 중요하지 않았다으로 기억할 수 없습니다.

+1

답변의 근거는 무엇입니까? 왜 필요한거야? 이점은 무엇입니까? – pstanton

+0

클립을 닫지 않으면 프로그램이 메모리 부족 병목 현상으로 인해 충돌 할 때까지는 문제가 없습니다. 이 문제가 발생한 응용 프로그램 : [link] (http://www.youtube.com/watch?v=3F06TdnnOjQ) – datahaki

+0

흥미 롭습니다. 나는 닫는 클립이 비싸다는 것을 발견했으며, 재생이 활성화되어있을 때 (다른 클립을 사용하여) 지연이 발생했다. 내가 이론을 다시 가비지 수집을 테스트하고, 아마도 모든 오디오 재생이 유휴 상태 일 때 대량으로 클립을 닫아야합니다. 닫을 때 지연을 알았습니까? 어떻게이 문제를 극복 했습니까? – pstanton

관련 문제