2012-09-22 32 views
0

好吧,我正在寫一個基本的遊戲,並決定使用MIDI聲音,因爲它們與MP3相比很小。我還決定使用它,因爲Java託管它自己的API,而不必使用第三方包含。使用所有內存的Java定序器? (7kb midi文件)

但是,當我運行一個通常爲7000字節左右的單個MIDI文件時,我的應用程序可用內存耗盡太多,以至於它經常會暫停/中斷甚至拋​​出異常。

我的實現是;

private class Track { 

    private Sequencer sequencer; 
    private Sequence sequence; 
    private int id; 
    private boolean loop; 

    public Track(final int id, final byte[] buffer, final boolean loop) throws IOException, InvalidMidiDataException, MidiUnavailableException 
    { 
     this.id = id; 
     this.sequence = MidiSystem.getSequence(new ByteArrayInputStream(buffer)); 
     this.sequencer = MidiSystem.getSequencer(); 
     this.loop = loop; 
    } 

    public synchronized boolean destroy() 
    { 
     this.id = -1; 
     this.sequencer = null; 
     this.sequence = null; 
     this.loop = false; 
     return this.sequencer == null; 
    } 

    public synchronized boolean play() throws InvalidMidiDataException, MidiUnavailableException 
    { 
     return play(loop); 
    } 

    public synchronized boolean play(boolean loop) throws InvalidMidiDataException, MidiUnavailableException 
    { 
     if(sequencer != null && sequencer.isRunning()) 
      sequencer.stop(); 
     sequencer.open(); 
     sequencer.setSequence(sequence); 
     sequencer.setLoopCount(Integer.MAX_VALUE); 
     sequencer.start(); 
     return sequencer.isRunning(); 
    } 

    public synchronized boolean stop() 
    { 
     if(sequencer != null && sequencer.isRunning()) 
      sequencer.stop(); 
     return sequencer != null && !sequencer.isRunning(); 
    } 

    public synchronized boolean playing() 
    { 
     return sequencer != null && sequencer.isRunning(); 
    } 

} 

目前我刪除一切圖形呈現來自應用程序來檢查我沒有泄漏在那裏的相關,但是這是造成問題。

它真的使用了超過70MB的RAM只是爲了一個7000字節的文件,這甚至可能嗎?

要檢查有多少內存可用,我只是繪畫;

graphics.drawString("Free: " + Runtime.getRuntime().freeMemory(), 10, 35); 

感謝您的任何幫助,將不勝感激。

+0

嗯,我已經看過它,每次我改變它的軌道它增加3線程,但不殺死前面的3? – ZBScripts

+0

您可以使用VisualVM來幫助追蹤這些類型的問題。我也會做一些研究並尋找與音頻API一起工作的代碼的例子。我沒有做太多的工作,但這不是最好的API,而且使用起來很不方便。 – Bill

+0

*「拋出異常。」*什麼例外?複製/粘貼堆棧跟蹤。 –

回答

0

看着它後,我發現'close'方法是停止同步器後停止使用內存所必需的。