Sun Java System Application Server Enterprise Edition 8.2 パフォーマンスチューニングガイド

Java プログラミング上の指針

この節では、Java のコーディングおよびパフォーマンスに関連する問題を扱います。これらの指針は Application Server に固有のものではなく、多くの状況で役立つ一般則です。Java コーディングのベストプラクティスについての詳細な解説は、「Java Blueprints」を参照してください。

直列化と直列化復元を避ける

オブジェクトの直列化と直列化復元は、CPU 負荷の高い操作であり、アプリケーションの動作速度を低下させる可能性があります。transient キーワードを使用して、直列化されるデータの量を減らします。また、一部のクラスでは、カスタマイズした readObject() および writeObject() メソッドが役に立つ場合があります。

文字列の連結に StringBuffer を使用する

パフォーマンスを改善するには、文字列連結を使用する代わりに StringBuffer.append() を使用します。

文字列オブジェクトは不変であり、作成後に変化することはありません。以下のコードを例に説明します。

String str = "testing";
str = str + "abc";

コンパイラはこのコードを次のように変換します。

String str = "testing";
StringBuffer tmp = new StringBuffer(str);
tmp.append("abc");
str = tmp.toString();

この例が示すように、コピーは本質的に負荷が大きい処理であり、使用しすぎるとパフォーマンスを著しく低下させる可能性があります。

不要になった変数に NULL を代入する

不要になった変数に明示的に NULL を代入すると、安全に再生できるメモリー上の部分をガベージコレクタが識別しやすくなります。Java はメモリー管理機構を備えていますが、メモリーリークや過度のメモリー使用を防ぐわけではありません。

オブジェクト参照を解放しないことにより、アプリケーションがメモリーリークを誘発する場合があります。それにより、Java ガベージコレクタがそれらのオブジェクトを再生できなくなり、結果的に使用中のメモリーの量が増加します。使用後に変数への参照を明示的に null にすることにより、ガベージコレクタがメモリーを再生できるようになります。

メモリーリークを検出する 1 つの方法は、プロファイリングツールを利用し、毎回のトランザクション後にメモリーのスナップショットを取ることです。安定した状態でリークのないアプリケーションは、ガベージコレクション後に安定したアクティブヒープメモリーを示します。

必要な場合にのみメソッドを final として宣言する

最近の最適化動的コンパイラでは、Java メソッドが final と宣言されていない場合でも、インライン化やその他の手続き間最適化を実行できます。キーワード final は元々の意図どおりに、すなわち、プログラムアーキテクチャー上の理由および保守性のために使用します。

final キーワードは、メソッドをオーバーライドしてはならないという確証がある場合にのみ使用してください。

定数を static final として宣言する

定数を static final 変数として宣言すると、動的コンパイラは定数畳み込み最適化を容易に実行できます。

ファイナライザを避ける

コードにファイナライザを追加すると、ガベージコレクタの負荷が大きくなり、動作が予測不能になります。仮想マシンは、ファイナライザが実行されるタイミングを保証しません。プログラムが終了する前にファイナライザが必ず実行されるとは限りません。クリティカルなリソースを finalize() メソッドで解放すると、アプリケーションの予測不能な動作を引き起こす場合があります。

メソッド引数を final として宣言する

メソッド引数がメソッド内で変更されない場合、その変数を final として宣言します。一般に、すべての変数について、初期化または何らかの値に設定されたあとに変数が変更されない場合はその変数を final として宣言します。

必要なときにのみ同期を行う

同期が必要な場合を除き、コードブロックまたはメソッドを同期しないでください。スケーラビリティーのボトルネックを避けるために、同期されるブロックまたはメソッドはできるだけ短くします。同期されないデータ構造については、より負荷が大きい java.util.HashTable などの別の方法の代わりに Java Collections Framework を使用します。

SOAP 添付には DataHandler を使用する

SOAP 添付に javax.activation.DataHandler を使用すると、パフォーマンスが向上します。

JAX-RPC 仕様では、次のことが規定されています。

結果として、Java の型マッピングを利用することによって、添付ファイル (.gif または XML ドキュメント) を SOAP 添付ファイルとして RPC スタイルの Web サービスに送信します。Web サービスの引数として (添付ファイルの MIME タイプにとって適切な) 必須の Java 型マッピングのいずれかを渡すとき、JAX-RPC ランタイムはこれらを SOAP 添付ファイルとして処理します。

たとえば、image/gif 添付ファイルを送信するには、java.awt.Image を使用するか、画像の DataHandler ラッパーを作成します。ラッパーを使用することの利点は次のとおりです。