Java ME code optimization
Article Metadata
J2ME applications usually do not run like native C++ applications. The performance is always penalized in terms of speed and memory footprint (RAM). For performance tuning of any J2ME application certain factors can be considered while writing programs(coding) like I/O, threading etc. This article contains tips discussing how to improve performance of a J2ME application by considering many such factors.
Tips
Creating and Discarding Objects
Object creation is very costly with respect to memory and performance overhead. new objects in Java can be created using the new keyword. So create objects only when its needed, don’t create objects in loop like
for (int i = 0; i < length; i++) {
ClassName p = new ClassName ();
results[i] = p.calculateResult();
}
Strings and StringBuffers
Whenever you are using substring or “+” it’s always creating a new string objects. So if you are manipulating strings in your code like substring, string concatenation, use StringBuffers or char array.
Optimize Loops
1. Use “for” loop over “while”: 2. Don’t calculate anything in condition of loop:
//bad
for (int i = 0; i < v.size(); i++) {
// Do something
}
//good
int size = v.size();
for (int i = 0; i < size; i++) {
// Do something
}
//better
for (int i = 0,n = v.size(); i < n; i++) {
// Do something
}
/*if the order in which you iterate through items is not important, you can iterate backward to avoid the extra local variable on the stack. Comparing against zero is almost always more efficient in any language*/
for( int i = v.size() - 1; i >= 0; i-- ) {
// Do something
}
Partition Your Application
The MIDP runtime environment loads classes as they are needed. Divide your big classes into small classes.
Only Include Classes You Need: Don’t use wild character imports like java.util.* instead of this use like java.util.Date;
Have public variables if its possible: Have variables public if possible, because if member variables are private to access them getter and setter methods are needed, calling them is a performance overhead, so if no validation is needed while modifying a variable have it public so that it can be easily accessed.
Avoid Threads
Whenever possible avoid threads in the midlet which are memory and CPU overheads. The activities like I/O are thread based only so its not possible to avoid threads then in such cases try to avoid I/O itself. For example if persistent storage is needed then use RecordStores instead of files.
When threads are used sometimes synchronization is also required which slows down the performance by at least 2/3 times, as maintenance of variables and their state is necessary as per the thread access.
Avoid Frequent opening of Recordstores
If using Recordstores, group the read and writes at one place as much as possible, this will require careful application design. Spreading RecordStore read and writes across the application will hamper the performance. Also RecordStore opening and closing operations needs to be minimized with proper design again.
Reuse GUI components
Reuse GUI components like Forms,TextBox etc. instead of creating them for every form if possible, this helps in keeping memory footprint low.
Use Appropriate type for variables
Though not much possible in J2ME but try to use appropriate types for variables. Using appropriate type of variable avoide wastage of RAM.
Reuse Variables
Try to reuse variables as far as possible, allocating to many auto variable slow downs the performance and consumes memory. Frequent allocation and deallocation of variables is an overhead. Bur reusing variables means making them global by allocating them in class, this should be carefully done without compromising on class design.
Array-spreading
Divide your multidimensional arrays into single dimensional arrays. Multidimensional array access is always a performance penalty, try to avoid them.
Calculations
Wherever possible try to use shift operator for mathematical calculation. int a = 11<< 1 instead of int a = 11* 2
Also avoid operations like multiplication and division as far as possible, they are costlier than addition and subtraction. Try to replace multiplication and division based computations using addition and subtraction as much as possible.
Use Native Methods
Like String.indexOf(), String.lastIndexOf()
Inner Classes
For inner classes choose package scope with static.
User obfuscater for j2me applications;
Don't call garbage collector in your code
System.gc();
Avoid synchronization, if you can Its very costly performance wise.
Managing loops whenever possible
Loops are computation overheads, though they make the life easy, so manage loops wherever possible. If the number of times the loop will be iterated is known in advanced then repeat few lines of code instead of having the loop to do that.
For example
for(int i = 0; i < 20; i++)
{
j += 10;
}
Above can be done as
for(int i == 0; i < 5; i++)
{
j += 10;
j += 10;
j += 10;
j += 10;
}
Try to keep Polymorphism away
In Java polymorphism really helps in designing a great code ( recall all design patterns ), but polymorphic behavior of class and method calls are the costliest calls in Java. The most efficient calls are static method calls, of course but not all methods can be static.


Most of those are done by the compiler.
You can import whatever you want, only the statically needed will really be imported.
Divisions and multiplications are optimized by the compiler too, as well as the '+', which is replaced by the compiler by a StringBuffer.
HashMap is not an existing Java ME Class.
One can only assume that manual garbage collection is only called when actually needed, usually for memory reasons, which overcomes performance reasons.
Too much optimization is just as bad as too few, so the first question to ask is: do i have performance issuses?
And a good design with the proper algorithm is often quite optimized already.
Avoid Adding ones Name in document:
The documents on WIKI are contributions of all users, and dont belong to a single one so please dont put your name at the bottom. Your contributions get recorded in edit history of the document.
--vdharankar
RecordStore
I don't quite agree with the paragraph regarding record stores : opening the recordstore in the startapp and keeping it open is the best way to corrupt data if the application is interrupted brutally.
Instead, I would recommend keeping the opening and the closing together, and to group as much as possible readings and writings in sequences
Above is logically correct and agree, added this to article, thanks !
-- vdharankar
Creating and discarding objects: be very wary about re-using objects. Objects that have been used for something else may be left in a different state to a fresh object, resulting in unexpected bugs.
Partition Your Application: when classes are loaded is at the discression of the implementation (within certain constraints). Classes are loaded as "needed". They are never unloaded, so it is hard to save memory by using more, smaller classes. Many small classes may slow down your application, because the classes will be loaded during execution rather than at start-up. That said, many small classes should be considered a best practice (though, from a software engineering perspective, not one of performance or memory optimization).
Partition Your Application: it is better only to import the classes you need. However, this has no affect on application size or performance, since imports do not generate code.
Partition Your Application: avoid public variables (or even non-local variables) as much as possible! Avoiding set/get methods might reduce size and increase performance, but can make code more liable to bugs and harder to read. The cost is rarely worth it.
Avoid Frequent opening of Recordstores: keeping record stores open for long periods of time may cause them to lose changes or become corrupt. This can occur if record stores are open when the application terminates, on some devices. I would usually recommend closing record stores as soon as possible after opening to avoid this problem. Record store performance can be enhanced by using fewer, larger records. In tests on a Nokia Series 40, reading a single record of 10,000 bytes was 80 times faster than reading 100 records of 100 bytes each (same number of bytes in total).
Reuse GUI components: re-using objects saves no memory, compared to discarding objects and creating fresh ones. See my first comment.
Use Appropriate type for variables: be vary careful about using types like byte and short, when int would do. The memory saving is minimal (there is no saving at all for local variables or parameters), code size will increase and performance will suffer. Java VMs always perform arithmetic on ints, and bytes and shorts require that conversion byte-codes be inserted into the code. Memory savings are much larger for byte[] or short[], however. Be careful to consider if the range of values might increase in the future (when porting to other devices, for example). Some people use byte for screen coordinates, forgetting that some screens are larger that 128x128.
Reuse Variables: local variables access much faster than non-locals, so non-local variables should be avoided. Re-using local variables for more than one purpose makes naming hard, and so can reduce readability. Re-use local variable slots in the stack frame by minimizing scope (declare variables inside {} blocks).
Calculations: beware that "a/2" and "a>>1" are not identical. A right-shift always rounds down, while division rounds towards zero. Hence "-3 >> 1 == -2" while "-3 / 2 == -1".