×

Discussion Board

Results 1 to 7 of 7
  1. #1
    Registered User
    Join Date
    May 2009
    Posts
    4

    Post Very little memory provided by Nokia 5800

    Hello developers,

    I have bought the new Nokia 5800 to develop touchscreen applications with Java ME.
    When I was loading and displaying some images the application crashed with
    Code:
    OutOfMemoryError
    .
    The application runs perfectly on my 5310 (Series 40 5th Edition, Feature Pack 1) and even on my old 6630 (S60 2nd Edition, Feature Pack 2).

    So I found out that the 5800 provides only 128 kB of memory. (5310: 2025 kB, 6630: 400kB)
    The values are the results of
    Code:
    Runtime.totalMemory()
    The 6630 is four years older than the 5800 and provides three times as much memory. May this be true?
    I have the latest firmware on the 5800 (V 21.0.025, 02-04-09)

    Does anyone have an idea?
    (What does "Maximum Heap Size: Unlimited" mean in "Device Details" -> "Memory Funktion"?)

    Thank you for your answers.

    Kindly regard
    Hannes


    PS: This is the little application's source code, I found out the amount of memory with

    Code:
    import javax.microedition.lcdui.*;
    import javax.microedition.midlet.*;
    
    public class MemoryTest extends MIDlet {
    
    	protected void startApp() throws MIDletStateChangeException {
    		Form form = new Form("MemoryTest");
    		form.addCommand(new Command("Exit", Command.EXIT, 0));
    		form.setCommandListener(new CommandListener() {
    			public void commandAction(Command c, Displayable d) {
    				notifyDestroyed();
    			}
    		});
    		Runtime runtime =Runtime.getRuntime();
    		form.append("FreeMemory: " + runtime.freeMemory());
    		form.append("TotalMemory: " + runtime.totalMemory());
    		Display.getDisplay(this).setCurrent(form);
    	}
    
    	protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
    	}
    
    	protected void pauseApp() {
    	}
    }
    And these are the results:

    Nokia 5800
    FreeMemory: 11436
    TotalMemory: 131072

    Nokia 5310
    FreeMemory: 2073856
    TotalMemory: 2097152

    Nokia 6630
    FreeMemory: 226120
    TotalMemory: 409600

  2. #2
    Super Contributor
    Join Date
    Jun 2003
    Location
    Cheshire, UK
    Posts
    7,395

    Re: Very little memory provided by Nokia 5800

    First... you must be careful using these methods, especially with Series 60 devices.

    Since the Java heap dynamically expands on Series 60s, "totalMemory" only tells you the current size of the Java heap, not the size to which it can expand. (The total size to which the heap can expand may change, as other applications are started and stopped on the device.) As your program demands more and more memory, the "totalMemory" figure will increase as the heap is expanded. This is what is meant by "unlimited"... of course, it isn't unlimited at all, you only have a finite amount.

    On some Series 60s, you may be able to find the total amount of free memory on the device with:

    Code:
    String freeRam = System.getProperty("com.nokia.memoryramfree");
    (Note that you see a much larger figure for totalMemory on the 5310. It's a Series 40 device, and Series 40s use a fixed-size Java heap. On these devices, totalMemory is telling you what you expect - how much memory you can use, in total.)

    "freeMemory" is also to be treated with caution. This is the amount of memory that is not currently allocated to any object. Sounds simple. However, "allocated objects" include garbage objects (objects that are unreachable by any thread). These remain allocated until the garbage collector deallocates them. If you watch freeMemory when running a program, you will usually see it drop gradually to zero, then jump up suddenly as the garbage collector kicks in.

    Not all objects are stored entirely inside the Java heap. Some objects may be stored partially outside the Java heap. This is particularly true of immutable (and possibly mutable) images, and some 3D graphics objects. This depends on device; Series 60 does this, as does Sony Ericsson's proprietary platform and some Samsung devices.

    As to why the 5800 is running out of memory... that would need a greater analysis of the application you're running. One possibility is that it is allocating image buffers equal to the screen size, and these are consuming much more memory on the 5800 because of its larger screen resolution.

    Hope that helps.

    Graham.

  3. #3
    Registered User
    Join Date
    May 2009
    Posts
    4

    Re: Very little memory provided by Nokia 5800

    Thanks Graham for the quick answer.

    System.getProperty("com.nokia.memoryramfree"); returned >57 MB on my 5800.
    (It seems that is depends on the internal flash memory, doesn't it?)

    I watched the results of several calls of Runtime.totalMemory(). It is exactly as so you wrote. It increased.

    I've done a deeper analysis of my application. The images reside in a large file (>500 MB) which is accessed with JSR-75. The OutOfMemoryError occures while skipping and reading the file before any image is created from the data.
    In this initialization phase the following is done:
    - mark the beginning of the file (inputStream.mark((int)fileConnection.fileSize());)
    - skip to almost the end (inputStream.skip(fileConnection.fileSize() - x);)
    - read a few bytes
    - jump to the beginning (inputStream.reset();)
    - skip and read some more bytes (< 100 bytes)

    No memory intensive operations are done (creating objects etc.) So I assume that the file operations lead to the error.
    I tried using a smaller file (5 MB). That works fine.
    On my 5310 and my 6630 it also works with the large file. Has the 5800 a bad JSR-75 implementation?

    Looking forward to the next answer
    Hannes

  4. #4
    Super Contributor
    Join Date
    Jun 2003
    Location
    Cheshire, UK
    Posts
    7,395

    Re: Very little memory provided by Nokia 5800

    When reading from the JAR with getResourceAsStream() (which I realize is not what you're talking about, but stay with me), quite a lot of devices load the entire resource file into memory before getResourceAsStream() returns. Some (if not all) Series 40s appear to do this. It sounds a little like the 5800 is trying to do something similar. My guess would be that InputStream.mark() is trying to allocate a byte[] to buffer the number of bytes specified in the argument, which would be about 500Mb.

    That doesn't entirely surprise me, though it is surprising that such a problem has been introduced after the 6630. The 6630 is quite old, and is from a particular crap era of Series 60 devices. I'm actually surprised that this application does work on the other two devices!

    One person has reported a nasty RMS problem on the 5800 (confirmed by Nokia), which is not a known Series 60 problem that I'm aware of, so perhaps there has been some tinkering with the Java implementation. Being unable to handle a mark() operation larger than the available memory is not really something I'd consider as "bad", given the general standard of Java implementation across devices from all manufacturers. But, being a buggier Series 60 than a 6630 would be quite bad! There has generally been an improvement in Series 60 devices, since the atrocity that is the 6600.

    If my guess is right, then removing the calls to mark() and reset(), and closing and re-opening the file instead, would probably make your problem go away. I'd guess you'd replace your problem with a new one, as you'd start getting more security prompts.

    Cheers,
    Graham.

  5. #5
    Registered User
    Join Date
    May 2009
    Posts
    4

    Re: Very little memory provided by Nokia 5800

    That's what I thought, too. But I didn't dare to write it.
    The Implementation is probably allocation as much memory as passed to InputStream.mark(). (On the 5310 I called InputStream.mark(Integer.MAX_VALUE) without any problem.)

    I will try to remove the calls to mark() and reset() and close and re-open the file. Close and re-open the InputStream should be enough, so hopefully I won't be whelmed with security prompts. That's the reason for reading from one large file instead of thounds of small files. I will report it later.

    When accessing a file on the 5800 I'm asked if I want to allow it once or for this session. So that ugly workaround might be quite transparent.
    By the way this choice does not correpond to the MIDP 2.1 API access rights. According to that "Ask first time" should not be available for "Read user data". But the JVM offers this option on the 5800 (fortunately).

    I have also noticed problems with RMS. That's the next thing I have to solve.

    If there are more ideas don't hesitate and post it.

    Thank you
    Hannes





    PS: With this quick-and-dirty source code I checked this phenomenon. It crashes on calling mark() on S60 (5800) and succeeds on S40 (5310).

    Code:
    import java.io.InputStream;
    
    import javax.microedition.io.Connector;
    import javax.microedition.io.file.FileConnection;
    import javax.microedition.lcdui.*;
    import javax.microedition.midlet.*;
    
    public class JSR75LargeFileTest extends MIDlet {
    
    	protected void startApp() throws MIDletStateChangeException {
    		//final to have access in inner classes
    		final Display display = Display.getDisplay(this);
    		final Form form = new Form("JSR75LargeFileTest");
    		final Command cmdTest = new Command("Test", Command.OK, 1);
    		final Command cmdExit = new Command("Exit", Command.EXIT, 0);
    		form.addCommand(cmdTest);
    		form.addCommand(cmdExit);
    		final TextField textField = new TextField("File URL", "file:///E:/largeFile.dat", 64, TextField.ANY);
    		form.append(textField);
    		form.setCommandListener(new CommandListener() {
    			public void commandAction(Command c, Displayable d) {
    				if (c == cmdExit) {
    					notifyDestroyed();
    				}
    				else if (c == cmdTest) {
    					form.deleteAll();
    					form.append(textField);
    					form.removeCommand(cmdTest);
    					new Thread() {
    						public void run() {
    							InputStream inputStream = null;
    							FileConnection fileConnection = null;
    							try {
    								form.append(new StringItem("Step 1", "Creating FileConnection and open InputStream"));
    								Thread.sleep(3000);
    								fileConnection = (FileConnection)Connector.open(textField.getString(), Connector.READ);
    								inputStream = fileConnection.openInputStream();
    								form.append(new StringItem("Step 2", "Call mark() on InputStream with file size"));
    								Thread.sleep(3000);
    								inputStream.mark((int)fileConnection.fileSize());
    								form.append(new StringItem("Step 3", "Jump to end of file - 1 byte"));
    								Thread.sleep(3000);
    								inputStream.skip(fileConnection.fileSize() - 1);
    								form.append(new StringItem("Step 4", "Read last byte"));
    								Thread.sleep(3000);
    								inputStream.read();
    								form.append(new StringItem("Step 5", "Jump to begin"));
    								Thread.sleep(3000);
    								inputStream.reset();
    								form.append(new StringItem("End", "Success"));
    							}
    							catch (Exception e) {
    								display.setCurrent(new Alert("Error", e.getMessage(), null, AlertType.ERROR));
    							}
    							finally {
    								try {
    									inputStream.close();
    								}
    								catch(Exception e) {
    								}
    								try {
    									fileConnection.close();
    								}
    								catch(Exception e) {
    								}
    							}
    						}
    					}.start(); //Thread
    					form.addCommand(cmdTest);
    				}
    			}
    		});
    		display.setCurrent(form);
    	}
    	protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
    	}
    
    	protected void pauseApp() {
    	}
    
    }

  6. #6
    Registered User
    Join Date
    May 2009
    Posts
    1

    Re: Very little memory provided by Nokia 5800

    Quote Originally Posted by grahamhughes View Post
    On some Series 60s, you may be able to find the total amount of free memory on the device with:

    Code:
    String freeRam = System.getProperty("com.nokia.memoryramfree");
    System.getProperty("com.nokia.memoryramfree") returns over 50 MiB on my 5800 phone, but I can't allocate more than 16 MiB of memory in my test application. The application creates byte[] objects and stores references in another array. It can allocate only 15 arrays of size 1 MiB or 252 arrays of size 64 KiB. Is JVM heap limited to 16 MiB on this device?

  7. #7
    Super Contributor
    Join Date
    Jun 2003
    Location
    Cheshire, UK
    Posts
    7,395

    Re: Very little memory provided by Nokia 5800

    Quote Originally Posted by nopiti View Post
    Is JVM heap limited to 16 MiB on this device?
    I have no idea, but your tests certainly suggest that it is.

    However, you may be able to use more memory than this, as some objects (like immutable Images) usually hold their data outside the Java heap on Series 60. (Unless 16Mb is some Symbian per-application limit, but I'm not aware of that.)

    Graham.

Similar Threads

  1. Infra-red capability
    By Symbian_Challenge_0412 in forum General Development Questions
    Replies: 1
    Last Post: 2005-08-16, 18:24
  2. Nokia Mobile VPN Client
    By marcyl in forum Symbian Networking & Messaging (Closed)
    Replies: 1
    Last Post: 2003-12-01, 14:47
  3. Series 60Series 60 MIDP Concept SDK Beta 0.2 Linux bug?
    By kauppi in forum Mobile Java Tools & SDKs
    Replies: 3
    Last Post: 2003-04-07, 09:05

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •