Skip to content

J2ME memory optimization tip. Multidimensional arrays.

Mobile phone is a resource constrained device, that imposes some challenges for application developers.

Quite often it is very convenient to use multidimensional arrays, though when doing so, we have to keep in mind that there is an overhead price to pay, that is, for every array object created, overhead == 16 bytes.
int array of size:0 uses 16 bytes of heap
int array of size:1 uses 20 bytes of heap
int array of size:2 uses 24 bytes of heap

For large data structures built with multidimensional arrays, you can oftentimes reduce the extra dimension overhead by an easy indexing change: convert every int[dim1][dim2] instance to an int[dim1*dim2] instance and change all expressions like a[i][j] to a[i*dim2 + j]. Of course, you pay a price from the lack of index-range checking on dim1 dimension (which also boosts performance).

For more tips on memory optimization, see javaworld’s java tip 130.

technorati tags:

String memory footprint on mobile (RAZR) and techniques to optimize it.

We are currently working on the application that will have to receive XML. There is a potential problem here, that it is not always known how big the payload will be. The problematic outcome is, it will simply blow the memory.

Here are the results of method that creates new string object of incremental size and analyzes the memory on the RAZR v3.
String of size:0 uses 56 bytes of heap
String of size:1 uses 64 bytes of heap
String of size:2 uses 64 bytes of heap
String of size:3 uses 72 bytes of heap
String of size:4 uses 72 bytes of heap
String of size:5 uses 80 bytes of heap
String of size:6 uses 80 bytes of heap
String of size:7 uses 88 bytes of heap
String of size:8 uses 88 bytes of heap
String of size:9 uses 96 bytes of heap
String of size:10 uses 96 bytes of heap
String of size:11 uses 104 bytes of heap
String of size:12 uses 104 bytes of heap
String of size:13 uses 112 bytes of heap
String of size:14 uses 112 bytes of heap
String of size:15 uses 120 bytes of heap
String of size:16 uses 120 bytes of heap
String of size:17 uses 128 bytes of heap
String of size:18 uses 128 bytes of heap

So you can see that the pure overhead of String object is 54 bytes, that means that if you have a whole bunch of short String objects, there is a potential for memory optimization, especially it concerns the XML parsers.
So thanks to the colleague of mine, who pointed me to this old post on javaworld, authored by Vladimir Roubtsov.

technorati tags:

Struts-Menu crashes

This issue has been bugging us for some time now. When under load that was emulated using openload, struts-menu 2.3 was crashing, throwing NullPointerException:

java.lang.NullPointerException
at net.sf.navigator.taglib.DisplayMenuTag.setLocation(DisplayMenuTag.java:217)
at net.sf.navigator.taglib.DisplayMenuTag.setPageLocation(DisplayMenuTag.java:173)
at net.sf.navigator.taglib.DisplayMenuTag.setPageLocation(DisplayMenuTag.java:205)
at net.sf.navigator.taglib.DisplayMenuTag.doStartTag(DisplayMenuTag.java:123)

The interesting thing is that it only happend on the Linux server and is not reproducible on WinXP boxes, so it looked like the issue with the jvm implementation. (This was just my guess and so far I have no better explanation). Below are the server details:

JBoss:
------
Version: 4.0.3SP1(build: CVSTag=JBoss_4_0_3_SP1 date=200510231054)
Version Name: Zion
Built on: October 23 2005

Environment:
------------
Start date: Wed Apr 12 22:38:03 PDT 2006
Hardware:
---------
#CPU: 4
OS: Linux 2.6.9-11.ELsmp (i386)
JVM Environment:
----------------
JVM Version: 1.5.0_05-b05 (Sun Microsystems Inc.)
JVM Name: Java HotSpot(TM) Server VM

Thank you Lord for open source.

Yes I mean it, if I would not have the access to the source code, how on earth would I be able to figure out the problem?!?!

So here are the details:

According to the stacktrace the exception is thrown here. Looking through the code revealed that menus are reinitialized on every request (should it be static and cached??) and it uses ArrayList to hold the submenu elements, see MenuComponent. Once I substituted ArrayList to Vector, the problem was gone.

Testing multithreaded app with j2meunit

As it’s parent junit , j2meunit does not have built-in support for threads. There for the only way to test threads is to add listeners to the code and do Thread.sleep(), which is a guess work most of the time.

So it was really great to stumble upon this blog post that provides some very good tips on testing threads with junit by utilizing GroboUtils.

I’m going to try groboUtils with j2meunit in the next two weeks myself. It would be really nice to find out if anyone has already tried it out and has some gotchas to share.

Extending J2MEUnit to publish the results

As those who use j2meunit to automate their testing already know, the problem is with viewing the results and gathering them, when tests run on real handset.

So I had to extend the original j2meunit to submit results to the server.

I had to create a new test runner that extends the j2meunit.midletui.TestRunner and overwrites siingle method, that is

/* (non-Javadoc)
* @see TestRunner#doRun(j2meunit.framework.Test)
*/
protected void doRun(Test suite) {
super.doRun(suite);
addToResultsList("Sending test results to the server.");
sendResultsToServer(aResult);
}

In the sendResultsToServer(TestResult result) all you have to do is gather the information you need from result, such as runCount(), errorCount(), failureCount() and go into details of iterating through result.errors() and result.failures(). In my case I send the over to the webserver as HTTP POST.

technorati tags:

Automated testing on handset

The plan is to use j2meunit to create automated testing of the application that will run on a mobile handset. There are some challenges with this. Mobile app development is actually quite full of challenges that most of j2ee developers forgot about or mostly don’t care about:

  1. Memory is very limited.
  2. Threads

So the main issue with testing is actually about #1, that is that on the target handset the limit size of the jar is 1MB. For the whole project it is quite enough (thanks to proguard for obfuscation). But in order to run tests project can not be obfuscated (try to figure out those stacktraces then), plus the size of the actual test code with the whole j2meunit adds to the size of the jar.

The idea now is to break down the scenarios and create a multiple jars with small set of tests. The outcome is one more challenge: how to deploy it to the handset , run the tests and gather the results. If we are talking about tens of jars right now, and might be hundreds at some point, it can be a real nightmare to manage.

I wonder how other people managed this?

technorati tags:

j2meunit reports

I’ve been working on setting up continuous integration of a j2me project using cruise control to fire up ant build. For compiling, packaging and obfuscation I use industry’s standard tools: antenna, and for unit testing I use the only available option: j2meunit. (Long live the SourceForge that hosts all of this open source projects.)
So I’ve got the scheduled build running, and CruiseControl is now sending build reports, everything is sweet. Except one thing: j2meunit does not produce xml reports, so CC does not recognize any output:

No Tests snapshot

Unit Tests: (0)
No Tests Run
This project doesn’t have any tests

Looking at j2meunit.textui.TestRunner it reveals that it only supports stdout as the output, so there is no build it xml reporting. I wonder if anyone came up with workaround on how to include j2meunit results into CruiseControl report??

As for me, I guess next step is to take a look how it is done in junit, and see if I would have time and ability to port it into j2meunit.

technorati tags: j2me j2meunit cruisecontrol

EclipseME generated build scripts and classpath

Yesterday I’ve found out that when I generated build script in EclipseMe by doing:

  • right click on project
  • J2ME/Export Antenna Build FileseclipseME screenshot

the project’s classpath is populated correctly everywhere, or better to say it is correctly defined and is referenced everywhere except wtkrun. For some strange reason wtkrun does not reference project’s classpath at all, so I had to add it myself, even though it is not recommended by EclipseME to change eclipse-build.xml.

So I had to add classpathref to the wtkrun task myself.

Technorati Tags:  j2meunit  eclipseme mobile  j2me  antenna