2008-09-19 18 views
2

我想用Java Midlet在諾基亞手機上反覆捕獲音頻片段。我目前的經驗是,使用Sun文檔中的代碼(請參閱:http://java.sun.com/javame/reference/apis/jsr135/javax/microedition/media/control/RecordControl.html)並將其包裝在「while(true)」循環中,但應用程序會慢慢佔用手機上的所有內存,程序最終會拋出異常並失敗開始進一步錄製。如果沒有JVM泄漏內存,您是否可以在諾基亞手機(N80/N95)上用Java Midlet錄製音頻?

消耗的內存不是Java堆內存---我的示例程序(如下)顯示Java內存大致保持靜態大約185,000字節---但底層支持庫中存在某種內存泄漏由諾基亞;我相信會發生內存泄漏,因爲如果您在運行Java應用程序一段時間後嘗試啓動另一個(非Java)應用程序(例如,Web瀏覽器),則手機將針對缺少內存的警告殺死該應用程序。

我已經嘗試了幾種不同的方法,從文檔中的Sun規範示例中採用了幾種不同的方法(每次初始化每個循環的循環,儘可能多地初始化一次,調用盡可能多的deallocate樣式的函數,絕對必要等)。似乎沒有成功。下面是一個簡單的示例程序,我認爲它應該可以工作,但在N80(儘管是固件更新)和N95上運行15分鐘左右後會崩潰。其他論壇也報告了這個問題,但在那裏提出的解決方案似乎不起作用(例如,請參見:http://discussion.forum.nokia.com/forum/showthread.php?t=129876)。

import javax.microedition.media.*; 
import javax.microedition.midlet.*; 
import javax.microedition.lcdui.*; 
import java.io.*; 

public class Standalone extends MIDlet { 

protected void startApp() { 

final Form form = new Form("Test audio recording"); 
final StringItem status = new StringItem("Status",""); 
form.append(status); 
final Command exit = new Command("Exit", Command.EXIT, 1); 
form.addCommand(exit); 
form.setCommandListener(new CommandListener() { 
    public void commandAction(Command cmd, Displayable disp) { 
     if (cmd == exit) { 
     destroyApp(false); 
     notifyDestroyed(); 
     } 
    } 
    }); 

Thread t = new Thread(){ 
    public void run() { 
     int counter = 0; 
     while(true) { 
     //Code cut 'n' paste from Sun JSR135 javadocs for RecordControl: 
     try { 
      Player p = Manager.createPlayer("capture://audio"); 
      p.realize(); 
      RecordControl rc = (RecordControl)p.getControl("RecordControl"); 
      ByteArrayOutputStream output = new ByteArrayOutputStream(); 
      rc.setRecordStream(output); 
      rc.startRecord(); 
      p.start(); 
      Thread.currentThread().sleep(5000); 
      rc.commit(); 
      p.close(); 
     } catch (Exception e) { 
      status.setText("completed "+counter+ 
        " T="+Runtime.getRuntime().totalMemory()+ 
        " F="+Runtime.getRuntime().freeMemory()+ 
        ": Error: "+e); 
      break; 
     } 
     counter++; 
     status.setText("completed "+counter+ 
        " T="+Runtime.getRuntime().totalMemory()+ 
        " F="+Runtime.getRuntime().freeMemory()); 
     System.gc(); //One forum post suggests this, but doesn't help 
     this.yield(); 
     } 
    } 
    }; 
t.start(); 
final Display display = Display.getDisplay(this); 
display.setCurrent(form); 
} 

protected void pauseApp() {} 
protected void destroyApp(boolean bool) {} 
}  

回答

0

我認爲你應該提交一個bugreport而不是嘗試解決這個問題。

1

N系列諾基亞設備存在已知的內存泄漏。它不是特定於Java,而是在某處的操作系統的底層。

最近工作在一款針對諾基亞N90的遊戲上,我遇到了類似的問題。我會遇到內存問題,這些問題會累積在應用程序的幾個不同的重新啓動中。解決方案只是爲了降低整體質量和遊戲資源的數量...

我會建議嘗試更新您的固件作爲新版本應該解決這個問題。但是,諾基亞並不是很容易升級固件,在大多數情況下,您必須將設備發送給諾基亞。而且,如果此應用程序不僅僅是供您個人使用,您必須期望任何使用N系列設備的人都不具備最新的固件。

最後,我會建議花一些時間在諾基亞論壇周圍尋找,因爲我知道有關於內存泄漏和N系列設備的帖子。這是一篇似乎解決您遇到問題的文章。

http://discussion.forum.nokia.com/forum/showthread.php?t=123486

+0

它,因爲它們是隨諾基亞軟件更新很容易更新諾基亞N系列手機的固件。我多次更新n95上的固件。 – Jimmy 2008-09-20 21:50:50

相關問題