2009年8月25日火曜日

java:WebSphereべからず集: 第9回 「スレッドを大量に生成して、使い捨てに�

WebSphereべからず集: 第9回 「スレッドを大量に生成して、使い捨てに�

avaで提供されているスレッド、java.lang.Threadは、比較的コストの大きいオブジェクトです。その生成や消滅には、通常のクラスのオブジェクトに比べて高い負荷をJVMにかけます。一般にこのようなオブジェクトは使い捨てにするのではなく、プールしてインスタンスを使いまわすような仕組みを作るのが望ましいといわれています。

加えて、java.lang.Threadには他の通常のオブジェクトにはない性質がいくつもあります。

たとえば、JDKの実装によっては、java.lang.Threadのインスタンスはヒープ中で自由に移動できないオブジェクト(pinned object)としてJavaヒープに格納されます。そのため、java.lang.Threadのインスタンスがヒープ中に多数あると、それらによって空き領域が分断されるため、連続した大きな空領域が作りにくくなる傾向があります。これによって、ヒープの(合計の)空領域は十分あるにもかかわらず、インスタンスの生成に失敗してOutOfMemoryErrorがでる、という障害が発生することがあります。

また、java.lang.ThreadのインスタンスはJavaのヒープ領域だけではなく、Nativeのスタック領域なども消費します。そのため java.lang.Threadが多数(数千個以上)あると、それらの領域を使い果たしてしまい、パフォーマンスが極端に悪くなったり、場合によっては JVMが異常終了することもあります。

ユーザースレッドを使用する場合には、スレッドをプールして使いまわすようにするべきです。そうすることにより、スレッドの生成・消滅による負荷を低減し、またプールサイズによって生成されるスレッド数の上限を固定することができます。

Javaでは、JDK/JRE 1.5(J2SE 5.0)から標準でスレッドプールが使用できるようになっています。しかし、WAS V5.1/V6.0が使用しているJDK/JRE 1.4や、WAS V4.0/V5.0が使用しているJDK/JRE 1.3では何らかの追加ライブラリーを使用する必要があります。

オープン・ソースで自由に使用できるスレッドプールの実装に、Doug Lea氏のutil.concurrentパッケージがあります。このライブラリーは、JSR-166で標準化され、J2SE 5.0から追加された並行実行ライブラリーの元となった実装です。util.concurrentパッケージの詳細については、以下の文書をご覧ください。

0 件のコメント: