J2ME Best Practices

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata
Created: senthilkumar05 (20 Dec 2007)
Last edited: hamishwillee (31 Jul 2012)






Java ME is becoming more sophisticated
● Very different from KVM-based stacks!
● Hardware acceleration, dynamic compilation,
runtime optimizations, advanced garbage collection,
3D graphics support, more…
● Tuned for certain code patterns and common constructs
● But breadth and depth of optimizations is limited
● Analysis and optimization constrained in space
and time
● Can't do “magic”
● Understanding platform properties is critical


● Increase the chances your code will run faster
● No guarantees: By definition can't target particular
implementations or specific features
● Focus on Java VM-level optimizations
● Disclaimer
● There are many different Java ME platforms out there!
We don't know them all. We haven't tried them all
● We can only make educated guesses about their
internal design and their properties
● Quantitative statements can be very difficult
● Your mileage will vary


Application startup
● Delay until user can interact with application
● One-time initialization and startup costs
● Long startup (>2 sec) is a major irritant
● Caused by jar loading, class loading/cp resolution, initialization, object creation, resource handling, UI setup


'Application execution speed and consistency
● Continuous low overall execution speed
● Long computation times get annoying
● Caused by lack of runtime optimizations, repeated failure to optimize, inefficient overall execution
● Repeated changes between fast and slow execution
● Inconsistent performance is hard to cope with
● Caused by shifting memory use patterns, garbage collection, undoing of existing optimizations due to resource constraints

 Application liveliness
● Repeated pauses and “hangs” during execution
● Feedback delays and pauses >50 ms are noticeable
● Caused by costly runtime optimization, code transformations, garbage collection

“Proficient Design”
● The basics of good application design and efficient code
 “Java VM-Friendly Design”
● Target properties and techniques of advanced Java ME platforms


 Big rules
● Choose an efficient algorithm
● A mismatched algorithm will never be efficient
● Reduce application startup time
● Interact with user as quickly as possible
● Do less work initially, initialize lazily or in background
● Note: Loading of resources, images particularly heavyweight
● Maintain responsiveness of UI
● Use threads for blocking or long-running operations
● Provide feedback to the user on what's happening

Efficient programming
● Use scalar types, local (i.e. stack) variables
● Pull invariants and string literals out of loops
● Avoid String.append() and String.equals()
● Use Exceptions only outside performance-critical code
● Release objects by setting references to them to null
● Use arrays instead of collections (Vector, HashTable)
● Cache results and objects locally where it makes sense
● Replace multiply and divide operations with shift
● Use best suited (read: efficient) library calls


More efficient programming
● Use Inner classes judiciously (extra space/time cost)
● Compare against 0, null, or false
● Use int instead of long where possible
● Use floating point carefully, as it is often emulated
● Avoid large or unnecessary synchronization blocks
● Avoid unnecessary object allocations
● Don't initialize class members to default value
● Try to avoid gc where visible to the user
● Obfuscate your code for size reduction


Advanced Java VM Techniques
● Hardware acceleration
● Static-/Ahead-of-time compilation (AOT)
● Just-in-time compilation (ADC)
● …or a combination of the above
● Garbage collection techniques
● Startup improvement techniques
● Often very platform-specific, not discussed
● Graphics- and UI-subsystem techniques
● Often external to Java VM, dominated by native code or hardware/graphics architecture. Not discussed


1) Static Array Initialization
● Problem
● Array initialization performed in static initializer
● This can cause significant code bloat and slow down class loading and initialization
● Impact
● Application startup, memory footprint
● Guideline
● Move initialization out of static initializer and do programmatic initialization or read data from I/O
● Note: Time vs. space trade-off (I/O can be slow)


Runtime Optimizations

2) Locality of Hot Code

● Problem
● Hot code spread out over multiple individual methods
● Optimization techniques typically operate on method boundaries (for semantical reasons)
● This multiplies overhead for hot spot detection, optimization, and subsequent management
● Impact
● Liveliness, execution consistency
● Guideline
● Factor/concentrate hot code in a few methods

3) Large Methods Containing Hot Code
● Problem
● Hot code embedded in large methods
● Optimization typically operates with method granularity
● Substantial hit taken for optimization of large body of code, and possible resource constraints or optimization failure (complexity or lack of resources)
● Impact
● Liveliness, execution consistency
● Guideline
● Keep methods with hot code compact

4) Mixing Hot and Cold Code
● Problem
● A section of code is hot but contains a number of code paths that don't execute often
● This results in large methods (see previous slide) and disrupts optimization and execution due to branches
● Impact -  Execution speed
● Guideline  --  Avoid mixing hot and cold code - all code in a hot method should really be hot

' ''''5) Conditional Exceptions in Hot Code

● Problem
● Code conditionally throws exceptions in the hot path
● This precludes certain optimizations (code reordering/rescheduling); exceptions are expensive
● Impact
● Execution speed
● Guideline
● Never throw unconditional exceptions in hot code
● Avoid conditional exceptions if possible
● Caveat: Might not always be practical due to implicit exception points such as null checks, array bounds, etc.

'6)  ''''System.gc()
● Problem
● Application periodically calls System.gc()
● Sophisticated memory management systems already dynamically adapt to a variety of conditions
● This means calls to System.gc()likely add overhead without any benefit (or even cause disruption)
● Impact  -  Execution speed
● Guideline  -  Don't call System.gc()

Use Device Resources Wisely


• Minimize application size
– Limit the number of features
– Object design – create single objects for common tasks and reuse them
– Place resource data on the server

' ''''Minimize runtime memory use
– Use scalar types (int, boolean) instead of objects (String, Integer)
– Don’t depend entirely on the garbage collector
    • Avoid creating a lot of objects quickly
    • Reuse objects
– Move computation to server
   • Perform data filtering, sorting, etc. on the server before sending it to the device
   • Completely process and manipulate data as needed before indicating to the user that new data has arrived. This  hides latency from user

'Code '''' Performance
• Use local variables
– Generally quicker to access local variables than class members
• Use threads for lengthy operations ( > than 1/10 second)
– Stop the operation from blocking the main UI thread
• Set appropriate access and declaration type
– Declare members as private whenever possible
– Declare classes as final if they will not be extended
– Carefully use static and final – understand the performance impact on both class and primitive types
• Carefully optimize loops and mathematical operations

This page was last modified on 31 July 2012, at 08:37.
44 page views in the last 30 days.