views:

891

answers:

2

I would like to repeatedly capture snippets of audio on a Nokia mobile phone with a Java Midlet. My current experience is that using the code in Sun's documentation (see: http://java.sun.com/javame/reference/apis/jsr135/javax/microedition/media/control/RecordControl.html) and wrapping this in a "while(true)" loop works, but the application slowly consumes all the memory on the phone and the program eventually throws an exception and fails to initiate further recordings.

The consumed memory isn't Java heap memory---my example program (below) shows that Java memory stays roughly static at around 185,000 bytes---but there is some kind of memory leak in the underlying supporting library provided by Nokia; I believe the memory leak occurs because if you try and start another (non-Java) application (e.g. web browser) after running the Java application for a while, the phone kills that application with a warning about lack of memory.

I've tried several different approaches from that taken by Sun's canonical example in the documentation (initialize everything each time round the loop, initialize as much as possible only once, call as many of the deallocate-style functions which shouldn't be strictly necessary etc.). None appear to be successful. Below is a simple example program which I believe should work, but crashes after running for 15 minutes or so on both the N80 (despite a firmware update) and N95. Other forums report this problem too, but the solutions presented there do not appear to work (for example, see: 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) {}
}
A: 

I think you should file a bugreport instead of trying to work around that.

Corporal Touchy
+1  A: 

There is a known memory leak with the N-series Nokia devices. It is not specific to Java and is in the underbelly of the OS somewhere.

Recently working on a game that targeted the Nokia N90, I had similar problems. I would run into memory problems that would accumulate over several different restarts of the application. The solution was just to reduce the overall quality and the amount of resources in the game...

I would recommend attempting to update your firmware as newer versions supposedly address this problem. However, Nokia does not make it very easy to upgrade the firmware, in most cases you have to send the device off to Nokia. And, if this app is not just for your own personal use, you have to expect anyone using the N-series devices to not have the latest firmware.

Finally, I would recommend spending some time looking around Forum Nokia as I know there are posts related to memory leaks and the N-series devices. Here is a post that seems to address the problem you are having.

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

Fostah
It very easy to update the firmware on nokia n series phones as they are shipped with the nokia software updater. I have updated the firmware on the n95 multiple times.
Jimmy
Thanks for the comment, that's very helpful as the N-series phones, and all Nokia phones I have are pre-2006 and I Nokia didn't do a great job of making this software known. Do you know if it works with older devices?
Fostah