インストラクション最適化
Java アプリをコンパイルした後のインストラクションに関して、以下のサイズ最適化が可能です。
nop の削除
「何もしない」という意味の nop 命令 は削除できます。
使用されないコードの削除
フロー制御の命令は条件分岐( if 系 )、無条件分岐( goto 系 )、メソッド呼び出し、の 3 種類に分類されます。フロー制御の属性として、例外に関する Exceptions があります。
スタート地点から到達できない命令列は削除できます。
未使用 'try-catch' ブロックの削除
Exceptions 属性で、発生しない例外の項目は削除できます。
goto 命令の削除・変更
サイズ削減のためにgoto 命令が削除・変更できる条件は次の 3 つです
- 次のインストラクションへ飛ぶ goto: この goto 命令は nop 命令と同じなので削除できます。
- goto へ飛ぶ goto: goto の飛び先を goto の飛び先である goto の飛び先に変更します。サイズは変わりませんが、実行効率が向上します。
- Rreturn/athrow へ飛ぶ goto: goto 命令を return/athrow に変更します。return/athrow 命令は goto 命令より短い命令です。また、プリベリファイ時に goto 命令の飛び先として StackMap として付加される情報も削減されます。
ローカル変数の並び順の変更
ローカル変数の操作を行う load 系, store 系の命令では、0 から 3 番目の変数にアクセスする命令が、他の命令より短くなっています。
load 系、store 系の命令でアクセスする変数を調べて、アクセス頻度の高い変数を 0 から 3 番までのインデックスに移すことで、サイズを削減できます。
未使用スタック命令の削除
「データを置く( push )」、「データを取り除く( pop )」が連続するスタック命令列は削除できます。
メソッドのインライン展開
小さなメソッドや、一ヶ所からしか呼び出されることの無いメソッドは、インライン展開すると全体としてサイズが削減されることがあります。
アクセスフラグの変更
クラス、メソッド、フィールドのアクセスフラグを同じにすることで、高い ZIP 圧縮が期待できます。
System.out.print[ln] の削除
System.out.print 系のメソッドは、コンソール出力用なので削除できます。
gc() の削除
ガーベッジコレクタを呼び出す命令 "Runtime.gc()" は削除できます。
その他 : JDK 1.4 のサポート
Java 2 SDK 1.4.2 でコンパイルされたアプリケーションの圧縮に対応します。