Optimizing Java for Size

[ index ] [ benchmarks | compilers | maintainability | resources | rules | speed | tools ]


Reducing code size is particularly important for Java applets, since it directly affects the time taken to download an applet. I'll list those issues specific to download times first, followed by general space-saving techniques.
Use JAR (or zip, or CAB) files:
To avoid the overhead of loading individual class and data files, JDK 1.1 supports Java archive (JAR) files. Previously, JDK 1.02 and Netscape Navigator 3.0 supported zip files, while Microsoft Internet Explorer 3.0 supported CAB files.

Don't reinvent API classes:
Use or extend a class from the Java API wherever possible. Sun has written the classes so that you don't have to. If you hate browsing through the online API, I recommend the annotated version in Java in a Nutshell.

Exploit inheritance:
Use inheritance in your own code: the more methods you can inherit, the less code you have to write.

Turn on compiler optimization:
Use javac -O. This inlines functions (which makes the bytecode bigger) and removes line numbers (which makes it smaller). Unless you use lots of inlinable functions, the removal of line numbers will dominate and your bytecode will get smaller. However, note that things can sometimes be inlined when they shouldn't -- see the compilers page for details.

Separate out common code:
Put code that is used in several different places into its own method (the reverse of inlining code for speed).

Don't initialize big arrays:
Although array initialization is a single statement in Java, the generated bytecode inserts one element at a time. If you've got a big array, this requires a lot of bytecode. You can save space by storing your data in a String and then parsing it into your array at runtime (tip from Andrew Scherpbier).

Dates are big (not just broken)
Date objects take a surprising amount of space for something with such limited functionality. If you're storing a lot of them, considering using longs instead, and recreating Date objects from them as necessary (tip from Jean-Marc Lugrin).

Use short names:
The names of visible entities (i.e., class, method and instance variable names) are listed in full in the class file, so using short names actually saves space. Code obfuscators such as Hashjava, Jobe, Obfuscate and Jshrink will rewrite your class files to use shorter (and incomprehensible) names.

Put static final constants in interfaces:
Constants defined using static final are included in the class file as well as being inlined. If you instead define them in an interface that you then implement, you can avoid this extra space overhead (tip from Paul Hepworth).

Watch for string concatenation:
Using + as a string concatenation operator will result in a method call if the operands are not compile-time constants. Unrolling a loop to eliminate string concatenation can therefore save space (tip from Luis Fernandes). Again, this might not be worth the effort. For example, the following loop is compiled into 48 bytes of bytecode:
  for (int i = 0; i < 3; i++){
    imgs[i] = getImage (getCodeBase(), "G" + i + ".gif");
  }
By unrolling the loop we eliminate the runtime concatenations and reduce the size of the bytecode to 39 bytes:
  imgs[0] = getImage (getCodeBase(), "G0.gif");
  imgs[1] = getImage (getCodeBase(), "G1.gif");
  imgs[2] = getImage (getCodeBase(), "G2.gif");
Note that the three instances of getCodeBase() are a good candidate for common subexpression elimination.

http://www.cs.cmu.edu/~jch/java/size.html Optimizing Java for Size
Last modified: Wed 18 Mar 1998 Copyright © 1996, 1997 Jonathan Hardwick