Optimizing Memory Use

Team-Fly

It's easy for J2SE programmers to be blasé about memory usage. After all, having a garbage collector means you don't have to worry about explicitly freeing memory-objects that are no longer in use will be magically harvested by the garbage collector, running in a low-priority thread. In the J2ME universe, however, memory is scarce and should be treated with respect. Furthermore, both the allocation of memory and the work of the garbage collector can drag down the speed of your application. In this section, we'll look at techniques for efficient object use, particularly with Strings and StringBuffers. Finally, I'll talk about gracefully handling the situation where there really isn't any memory left.

Creating and Discarding Objects

If you're creating a new object inside a loop, it should be setting off alarm bells in your head. Every time you create an object (using new), memory is allocated. Allocating memory takes time. Worse, objects created at the beginning of a loop are likely to fall out of scope by the end of the loop, which means that each iteration through the loop pushes the runtime system closer to running the garbage collector. Here's an example:

 // Set up the inputs and results arrays. Object[] inputs = new Object[0]; int[] results = new int[0]; // Process each input to calculate a result. int length = inputs.length; for (int i = 0; i < length; i++) {   Processor p = new Processor(inputs[i]);   results[i] = p.calculateResult(); } 

Creating objects in a loop imposes a double penalty in terms of performance. You pay a price up front when the object is first created, then later when the object is garbage collected.

You can almost always restructure your code to avoid this problem. For example, instead of creating a new Processor for each input, you could do something like this:

 // Set up the inputs and results arrays. Object[] inputs = new Object[0]; int[] results = new int[0]; // Process each input to calculate a result. int length = inputs.length; Processor p = new Processor(); for (int i = 0; i < length; i++) {   p.setInput(inputs[i]);   results[i] = p.calculateResult(); } 

Strings and StringBuffers

Strings have a special status in Java. They are the only objects for which the plus operator '+' is overloaded. Each time you concatenate strings using the plus operator, be wary-behind the scenes, new String and StringBuffer objects are probably being created for you.

String and StringBuffer share a curious relationship. When you can create and modify a StringBuffer, the actual work is performed on an internal character array. When you create a String from the StringBuffer, the String points to the same character array. Everything is fine so far, right? But if you further modify the StringBuffer, it cleverly creates a new character array, a copy of the old one. Thus, while StringBuffer is generally an efficient way to create Strings, it is not always obvious exactly when new objects are created.

The moral of the story is that every place you see string concatenation, there may be new objects being created. If you're assembling strings inside a loop, you should think about a different approach, possibly involving StringBuffer. Another possible optimization is to forego String and StringBuffer entirely and just use character arrays. While this may be a fast and efficient solution in your own code, keep in mind that many APIs require Strings as parameters and return Strings from methods, so you may end up doing a lot of conversion between character arrays and Strings.

Failing Gracefully

Given the paucity of memory in a typical MID, your application should be prepared for disappointment each time it asks for memory. Each time objects are created, your code should catch java.lang.OutOfMemoryError. It is far better for you to catch OutOfMemoryErrors than for your host environment to catch them. You, at least, have a chance to do something reasonable-free up some memory and try again, or fail gracefully with a politely worded message to the user. The host environment is not likely to be so kind, and user perception of your application will be much worse.


Team-Fly


Wireless Java. Developing with J2ME
ColdFusion MX Professional Projects
ISBN: 1590590775
EAN: 2147483647
Year: 2000
Pages: 129

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net