ナビゲーションをスキップ

アプリケーションの開発

  前 次 前/次ボタンと目次ボタンとの区切り線 目次  

推奨されるコーディングのプラクティス

この節では、BEA JRockit で実行するアプリケーションを記述するためのガイドラインを示します。ここで提供する情報は包括的なものではありませんが、一般的な落とし穴を回避するのに役立ちます。BEA Systems は Java の「write once run everywhere」という概念を妥協することはありません。その一方で、この節では Java プログラムにとって有用なガイドラインを示します。ただし、これらのガイドラインは、概して JVM 同士、特に Sun Microsystems の HotSpot JVM と BEA JRockit JVM の間で切り替えるときに非常に重要です。

ベスト プラクティスのコーディングの内容は以下のとおりです。

 


関連する仕様を読む

Java 言語仕様と Java API 仕様をよく読んで、指定されていない動作には依存しないようにします。

BEA JRockit JVM は Java 仮想マシン仕様や Java API 仕様などのさまざまな仕様に基づいています。これらの仕様には多数の実装があり、BEA JRockit がその 1 つであることに注意してください。これらのドキュメントで指定されていない特別の動作は想定しないようにする必要があります。指定されていない動作は Sun JVM と BEA JRockit JVM で異なることがあります。また、Sun JVM の個々のリリースや、BEA JRockit JVM の各リリース間でも異なる場合があることに注意してください。

これらの仕様は以下のサイトにあります。

仕様は、JVM ベンダに JVM を最適化する自由を与えるように記述されているため、指定されていない特定の動作があります。上記の仕様には指定されていない部分が多数あることを理解しておく必要があります。以下の例で、そのような指定されていない要素を 3 つ紹介します。

例 1: リフレクション

java.lang.ClassgetMethods() メソッドに関する Java API 仕様では、「返された配列内の要素は、ソートされていたり、特定の順序になっていることはありません」と明記されています。

例 2: リフレクション (2)

java.lang.reflect.MethodtoString() メソッドにはアクセス修飾子 native を含めることができます。そのため、この呼び出しの結果が JVM 実装同士で同じであるということに依存しないでください。Java API 仕様の一部のクラスは BEA JRockit JVM と Sun JVM のいずれでも native として実装されます。ある JVM のネイティブ実装が別の JVM でもネイティブであるという保証はありません。

例 3: シリアライゼーション

java.lang.ObjectInputStream クラスの defaultReadObject() メソッドに関する Java API 仕様では、デシリアライズされるフィールドの順序が指定されていないため、このような順序を予期することはできません。

 


非推奨の安全でないメソッドを使用しない

以下のメソッドは非推奨です。

上記のメソッドは本質的に安全ではないため、使用しないでください。詳細については、以下を参照してください。

http://java.sun.com/j2se/1.4/docs/guide/misc/threadPrimitiveDeprecation.html

 


ファイナライザの使用を最小限に抑える

ファイナライザは実行の順序に暗黙的に依存することがよくあるため、エラーが発生しやすくなります。この順序は JVM 間でも、同じ JVM 上の連続した実行同士でも異なります。また、ファイナライザを使用すると、メモリ管理システムはファイナライザの実行を処理し、オブジェクトをより長くアクティブにしておく必要があり、余分な負荷がかかるため、本質的にパフォーマンスに良くありません。ファイナライザの使用方法 (および使用しない方法) の詳細については、以下を参照してください。

http://access1.sun.com/techarticles/weak.references.html

http://www.memorymanagement.org/glossary/r.html#reference.object

 


スレッドの優先順位に依存しない

java.lang.Thread.setPriority を使用する場合は注意してください。スレッドの優先順位に依存すると、望まないまたは予期しない結果を引き起こす可能性があります。スケジューリング アルゴリズムは CPU 時間の優先順位の低いスレッドを選択しないまま、そのスレッドを永久に実行しない可能性があるためです。さらに、その結果はオペレーティング システムや JVM 間で異なる場合があります。

Java API 仕様には、「各スレッドには優先順位が付けられています。優先順位の高いスレッドは、優先順位の低いスレッドよりも優先して実行されます」と記述されています。

setPriority() メソッドによって設定される優先順位は、スレッドスケジューリング アルゴリズムで使用されるパラメータであり、CPU 時間を実行スレッドに分配するものです。このアルゴリズムは JVM またはオペレーティング システムによって制御されます。このアルゴリズムは通常オペレーティング システム間で異なり、オペレーティング システムと JVM の各リリース間でも異なる場合がある点に注意することが大切です。BEA JRockit JVM のネイティブ スレッドの場合、アルゴリズムはオペレーティング システムで実装されています。

 


内部的な sun.* または COM.jrockit.* クラスを使用しない

BEA JRockit に含まれるクラスは、java.*javax.*org.*sun.* および COM.jrockit.* のパッケージ グループに分類されます。sun.*COM.jrockit を除くすべてのパッケージは、Java プラットフォームの標準部分であり、将来もサポートされます。一般に、Java プラットフォームに含まれていない非標準のパッケージは、JVM ベンダと OS プラットフォーム (Windows、Linux など) にわたって異なることがあり、SDK のバージョンごとに予告なくいつでも変更される可能性があります。sun.* および COM.jrockit.* パッケージの直接の使用が含まれるプログラムは 100% Pure Java ではありません。

詳細については、以下の sun.* パッケージに関する注意を参照してください。

http://java.sun.com/products/jdk/faq/faq-sun-packages.html

 


java.util.Hashtable を使用する場合はユーザ定義クラスの java.Object.hashCode をオーバーライドする

BEA JRockit JVM で、hashCode の現在のデフォルト実装は、JVM によって決定されるオブジェクトの値を返します。値はオブジェクトのメモリ アドレスを使用して作成されます。ただし、ガベージ コレクション中にオブジェクトが移動される場合、この値は再利用できるため、2 つの異なるオブジェクトに対する同じハッシュ コードを取得することが可能です。また、同じ値を表す 2 つのオブジェクトは、まったく同一のオブジェクトである場合にのみ同じハッシュ コードを持つことが保証されています。この実装はハッシュ化にとってあまり便利ではないため、派生クラスでは hashCode() をオーバーライドする必要があります。

 


スレッドの同期は慎重に行う

共有データにアクセスするスレッドを同期していることを確認してください。JVM を変更すると同期化のバグが発生することがよくあります。ロック、ガベージ コレクション、スレッド スケジューリングなどの実装が大きく異なる可能性があるためです。

 


標準のシステム プロパティのみを想定する

java.lang.System.getProperties() または java.lang.System.getProperty() を実装する場合は、返される標準のシステム プロパティにのみ依存する必要があります。VM が異なると、拡張プロパティの別のセットを返す可能性があります。非標準のプロパティが返されないようにしてください。

JVM は起動時に、システム プロパティ リストに多数の標準プロパティを挿入します。これらのプロパティとその値の意味は、Java API 仕様で示されています。これ以外の非標準のプロパティを予期しないようにしてください。

http://java.sun.com/j2se/1.4/docs/api/java/lang/System.html#getProperties()

 


Java プロセスの数を最小限に抑える

アプリケーションを設計するときに、複数のプロセス (JVM インスタンス) を実行するか、単一のプロセス (JVM インスタンス) の内部で複数のスレッドまたはスレッド グループを実行するかを選ぶ場合があります。可能な場合は、1 つの物理マシンごとにできる限り少ない JVM インスタンスを使用するほうが効率的です。

 


System.gc() を呼び出さない

java.lang.System.gc() を呼び出さないでください。このメソッドは BEA JRockit と他の JVM とでは異なる動作になります。Sun JVM や他の JVM のように完全なガベージ コレクションを行う代わりに、BEA JRockit で動作するアプリケーションによって呼び出される場合、System.gc() は既に使用中のガベージ コレクタによって動作が異なります。

注意 : System.gc() を呼び出す必要がある場合は、コマンドライン オプション -XXfullsystemgc を使用して、BEA JRockit JVM の動作をオーバーライドするとよいでしょう。

一般に、BEA JRockit JVM のガベージ コレクタは、ガベージ コレクションの実行時期の決定を System.gc() よりも効果的に行います。メモリ使用状況やガベージ コレクションの休止時間などで問題がある場合は、BEA JRockit JVM のメモリ管理システムを適切にコンフィグレーションしてください。『BEA JRockit JVM チューニング ガイド』の「BEA JRockit JVM のチューニング」を参照してください。

 

ビゲーション バーのスキップ  ページの先頭 前 次