Resource Packing

Property settings

This optimization is turned ON by default.
In the property file,
OPT.RESOURCE.PACKING=ON turns on this optimization
OPT.RESOURCE.PACKING=OFF turns off this optimization

Resource packing reduces the overall size of a MIDlet's JAR file by automatically packaging the resource files available to the application into a small number of special packed resource files. The packed resource files have greater compressibility, and by reducing the number of files it helps to reduce the overhead in the JAR file. Although resource packing can be done programmatically in Java, mBooster implements very efficient algorithms that would for most circumstances result in significantly smaller overall JAR files. In addition mBooster allows you to vary the key parameters for resource packing without altering any source code. This flexibility is particularly useful when you are building multiple SKUs for different devices.

Warning

You MUST
if the application
  • uses any method within the system library to access the resource files, except through:
    1. public java.io.InputStream java.lang.Class.getResourceAsStream(java.lang.String), defined in CLDC 1.0 API
    2. public static javax.microedition.lcdui.Image javax.microedition.lcdui.Image.createImage(java.lang.String), defined in MIDP 1.0 API
    3. public com.sprintpcs.media.Clip(String resource, String MIMEType, int priority, int vibration), defined in Sprint API
    4. public static javax.microedition.m3g.Object3D[] javax.microedition.m3g.Loader.load(java.lang.String name), defined in JSR-184 API
    5. public com.vodafone.v10.sound.Sound(String file), defined in Vodafone VSCL API
  • OR loads an M3G file through the JSR-184 API, where the file contains an external reference to an M3G or PNG file that is resource packed,
  • OR defines a subclass of com.sprintpcs.media.Clip, a class defined in the Sprint API

Resource packing optimization is currently not supported for DoJa applications. This optimization will be automatically turned off when optimizing an DoJa i-appli, i.e. when the property JVM.PLATFORM is set to J2ME_DOJA.

Resource packing optimization can be configured in a flexible manner through this set of properties. Resource packing optimization operates in two distinct modes with different sets of configuration parameters.

These two different modes have tradeoffs as follows:

Load-On-Demand Mode Preload Mode
Configuration complexity Simple - no understanding of resource file access pattern required Requires understanding of resource file access pattern
Heap memory usage Increased - proportional to RESOURCE.PACKING.MAX.PACK.SIZE Typically little or no increase in peak heap memory usage in real-life applications
Resource file access performance Performance degraded Performance significantly improved

In addition Resource Packing Optimization can also be configured as Profiling Mode, a special mode which does not do resource packing but can help to configure settings for Preload Mode.

Load-On-Demand Mode

Resource packing optimization operates in this mode when RESOURCE.PACKING.MODE is set to 1.

When operating in Load-On-Demand Mode, mBooster injects code into the application to intercept resource file accesses. Whenever the application requests access to a resource file, the injected code would intervene. Instead the application would access the resource pack file, and return the section of the resource pack file that corresponds to the requested file.

Be Careful

Resource Packing Optimization, when operating in Load-On-Demand Mode, can make a significant difference in the overall size of the optimized application, but it has two important side effects:
  • It is likely to increase the peak heap usage of the optimized application,
  • The performance of calls used to access resources will decrease.

If your application is very tight in heap memory, please see Resource Packing And Heap Usage for more information.

If your application frequently accesses resource files, please consider switching to Preload Mode to alleviate performance issues when they arise.

Tips
  • Generally midlets are written such that the paths used to identify resource files are always given as absolute paths, without using backslashes, and without needing the special directories ('.' and '..'). When the user is certain that the midlet has been written in this way, it is recommended to set the property RESOURCE.PACKING.PARSE.COMPLEX.PATHS to OFF to reduce the optimized application by a further 200-400 bytes.
  • The property RESOURCE.PACKING.EXCLUDE can be used to explicitly exclude a resource file from resource packing. If a particular resource file is known to be accessed frequently, explicit exclusion from the resource packing may improve performance.
 

Preload Mode

To enable Preload Mode, the property RESOURCE.PACKING.MODE must be set to 2

Preload Mode introduces the concept of preload group. One or more resource files belong to a preload group. The user specifies one or more preload groups through the properties RESOURCE.PACKING.PRELOAD.GROUP.<N>, where N is 1 to 99.

When operating in Preload Mode, mBooster injects code into the application to intercept resource file accesses. Whenever the application requests access to a resource file, the injected code would intervene:

  1. The preload group to which the requested resource file belongs is determined.
  2. If the requested preload group is not currently cached OR the requested resource file is not currently present in the cache, the currently cached preload group is released. Every resource file belonging to the requested preload group is loaded and cached in the heap memory.
  3. The requested file is returned, and its cached copy deallocated. Please note that other resource files in the same preload group remain cached.

When correctly configured, Preload Mode will generally speed up the execution of resource-file-access-intensive applications through caching related files specified in the same preload group. When correctly configured the application's peak heap memory usage is likely to remain approximately the same.

To produce optimal performance and minimum JAR file size, it is essential to specify the preload groups "correctly" to match the pattern of resource file access. To determine the optimal preload groups, it is recommended to instrument the application by running Resource Packing Optimization in Profiling Mode.

Given the console output from the instrumented application, consider the following points as how to form suitable preload groups for Preload Mode:

  1. The resource files allocated to the same preload group should be accessed at approximately the same time:
    • Given a preload group with two files A and B, when file A is requested, both A and B are loaded into memory, then A is deallocated as it is returned. B will be using up heap memory until it is later requested, which may cause unacceptable strain on the memory of the application.
  2. The accesses to resource files in a given preload group should never be interleaved by an access to a resource file in a different preload group:
    • If the first preload group is loaded into memory, and only half of the files in the preload group are requested and removed, then when a file in a different preload group is requested, the remaining files in the first preload group are discarded from memory.
  3. The resource files in a given preload group should not be requested multiple times without other members of the same preload group also being requested:
    • If a preload group containing files A, B, and C is loaded following a request for file C, the files A and B will be held in memory after file C is returned. If then file C is requested again, A and B will be discarded and immediately re-loaded into memory along with C.
    • If perhaps it is only a small number of files that are discarded and re-loaded in such a situation, then this wastage may be acceptable to the application
Some applications may access resource files in a seemingly random way, and therefore it is not possible to form suitable preload groups. These application are unsuitable to be resoutce packed with Preload Mode.

Simple Business App

Consider a simple business application which we know to have three separate modes, and a main menu. Say we get the following profile output from profiling:

Loading main menu...
[RESOURCE FILE ACCESS 1137481749015] /title1.png
[RESOURCE FILE ACCESS 1137481749015] /bg1.png
[RESOURCE FILE ACCESS 1137481749015] /bg2.png
[RESOURCE FILE ACCESS 1137481749015] /bg3.png
[RESOURCE FILE ACCESS 1137481749025] /select.au
Loading email client...
[RESOURCE FILE ACCESS 1137481755000] /email.png
[RESOURCE FILE ACCESS 1137481755000] /sent.png
[RESOURCE FILE ACCESS 1137481755000] /inbox.png
[RESOURCE FILE ACCESS 1137481755000] /outbox.png
Loading main menu...
[RESOURCE FILE ACCESS 1137481785105] /title1.png
[RESOURCE FILE ACCESS 1137481785105] /bg1.png
[RESOURCE FILE ACCESS 1137481785105] /bg2.png
[RESOURCE FILE ACCESS 1137481785105] /bg3.png
[RESOURCE FILE ACCESS 1137481785105] /select.au
Loading address book...
[RESOURCE FILE ACCESS 1137481821000] /layout.dat
[RESOURCE FILE ACCESS 1137481821005] /friends.png
[RESOURCE FILE ACCESS 1137481821020] /business.png
Loading main menu...
[RESOURCE FILE ACCESS 1137481861000] /title1.png
[RESOURCE FILE ACCESS 1137481861000] /bg1.png
[RESOURCE FILE ACCESS 1137481861000] /bg2.png
[RESOURCE FILE ACCESS 1137481861000] /bg3.png
[RESOURCE FILE ACCESS 1137481861000] /select.au
Loading calendar...
[RESOURCE FILE ACCESS 1137481864045] /weekdays.png
[RESOURCE FILE ACCESS 1137481864045] /months.png
[RESOURCE FILE ACCESS 1137481864045] /digits_small.png
[RESOURCE FILE ACCESS 1137481864045] /digits_large.png
Loading main menu...
[RESOURCE FILE ACCESS 1137481874540] /title1.png
[RESOURCE FILE ACCESS 1137481874540] /bg1.png
[RESOURCE FILE ACCESS 1137481874540] /bg2.png
[RESOURCE FILE ACCESS 1137481874540] /bg3.png
[RESOURCE FILE ACCESS 1137481874540] /select.au
Exiting...

By analysing the resource files that are accessed as the application is run, and understanding how they correspond to the different modes of the application, we can identify some patterns that indicate some useful Preload Groups:

  • Every time the main menu is loaded, /title1.png, /bg1.png, /bg2.png, /bg3.png, and /select.au are requested. These files are not loaded at any other time. Therefore they make a suitable Preload Group.
  • For the email client, address book, and calendar mode, there is a distinct set of files loaded each time. Since these sets do not overlap or contain any repeats, we can easily make them into a Preload Group each.
For this application, a perfect set of groups specified would be:
RESOURCE.PACKING.PRELOAD.GROUP.1=/title1.png;/bg1.png;/bg2.png;/bg3.png;
    /select.au 
RESOURCE.PACKING.PRELOAD.GROUP.2=/email.png;/sent.png;/inbox.png;/outbox.png
RESOURCE.PACKING.PRELOAD.GROUP.3=/layout.dat;/friends.png;/business.png
RESOURCE.PACKING.PRELOAD.GROUP.4=/weekdays.png;/months.png;/digits_small.png;
    /digits_large.png
Tips
  • Generally midlets are written such that the paths used to identify resource files are always given as absolute paths, without using backslashes, and without needing the special directories ('.' and '..'). When the user is certain that the midlet has been written in this way, it is recommended to set the property RESOURCE.PACKING.PARSE.COMPLEX.PATHS to OFF to reduce the optimized application by a further 200-400 bytes.
  • Avoid writing code that unnecessarily accesses the same resource file twice. This typically represents a bad coding practice, and introduces unnecessary performance overhead. Furthermore, it significantly reduces the effectiveness of the Preload Mode.

Resource packing and heap usage

This section applies to Load-On-Demand Mode, and to a lesser degree Preload Mode.

When optimizing applications with high heap memory usage, the effect of resource packing needs to be considered carefully. On some handsets including Nokia series 40, the loading of a resource from a pack file requires a substantial amount of free heap memory, roughly equivalent to the size of the pack file. If the required heap memory is unavailable, the optimized application will fail to run on the handset, even though the emulator may still run the application as it may model the handset memory limits inaccurately.

The maximum size of the pack files is configured by setting the RESOURCE.PACKING.MAX.PACK.SIZE property. Setting this property will place an upper limit on the size of the pack files produced by mBooster, and so place a limit on the heap memory required to load a resource from a pack file.

We recommend that when optimizing for heap memory constrained devices such as Nokia Series 40, you thoroughly test the heap usage of your application after mBooster optimization. If the optimized application runs out of heap memory, please consider reducing the value of the RESOURCE.PACKING.MAX.PACK.SIZE property, switching to Preload Mode, or in the worst case switching off Resource Packing optimization entirely by setting OPT.RESOURCE.PACKING property to OFF.

Typically you should be able to significantly reduce the application size while satisfying the heap memory limit, through setting RESOURCE.PACKING.MAX.PACK.SIZE appropriately, or switching to Preload Mode.

Profiling Mode

To enable Profiling Mode, the property RESOURCE.PACKING.MODE must be set to 3

In Profiling Mode, no resource packing occurs, instead the optimized application is instrumented with method calls that print information to the console whenever the application accesses a resource file.

When the instrumented application is run in an emulator, it will generate messages to the console. To provide useful profiling information, the whole application should be fully exercised. That means you should try to run the application in a way that generate every single possible combination or sequence of resource file access.

The format of the information printed to the console is:

[RESOURCE FILE ACCESS _TIMESTAMP_] _FILENAME_

where 
* _TIMESTAMP_ is given in milliseconds
* _FILENAME_ is the filename passed to the library method 
    used to access the named resource

Previous pageContentsNext page