| Java言語の特長は、プログラム内で簡単にマルチスレッドを利用できる点にあります。しかしこれは、いわば諸刃の剣です。なぜなら、マルチスレッド・プログラミングに習熟していないプログラマがスレッドをむやみに利用すると、問題を生じることが多々あるからです。
 |
 |
| 図1:Glance/gpmによるJavaスレッドのモニタリング |
図1は、HP-UXに付属するツールGlance/gpmを利用して、実行中のJVMプロセス内で動作する全てのスレッドを表示した例です。ここでは、JVMが内部的に使用する11のスレッドに加えて、Javaアプリケーションの実行にともない生成された複数のスレッドが表示されています。こうしたスレッドを多用するJavaアプリケーションのプログラミングでは、スレッドを無制限に生成しないよう配慮する必要があります。また、以下の2つのポイントに気をつけなくてはなりません。
【OSの上限数を越えるスレッドを作成しない】
大半のJVMでは、OSのスレッドを利用してJavaスレッドを実装しています。よって、Javaスレッドをあまりに大量に生成すると、OSが定める1プロセスあたりのスレッド数の制限を超えてしまうのです。こうした場合、Javaプログラムの実行中にOutOfMemoryエラーが発生したり、「スレッドが多すぎる」と指摘するメッセージが表示されたりします。
もっとも、この問題への対処は比較的簡単です。HP-UXの場合、HPが提供するツール「HPjconfig」を利用することで、カーネル・パラメータ「max_thread_prod」に設定すべき推奨値を算出できます。この値をもとに、管理ツール「SAM」を利用して同パラメータの変更を行います。HPjconfigは、以下のWebサイトからダウンロードできます。
【ロックを長時間保持しない】
複数のスレッド間でリソースを共有するアプリケーションでは、あるスレッドがリソースのロックを長い間保持してしまうと、他のスレッドの処理が停止してしまいます。この状態をロック競合といいます。ロック競合の起こりやすさは、ロックを獲得しようとするスレッドの数と、獲得の頻度によって決まります。ロック競合が過大に発生すると、スレッドは有意義な作業を進めることができず、ロックの解放待ちに大半の時間を費やしてしまいます。
この2つのうち、Javaのパフォーマンス・チューニングでは、ロック競合の軽減が重要なポイントになります。ロック競合はアプリケーションの設計のまずさに起因して発生するため、設計変更によってその大半は解消できます。そこで以下、このロック競合問題の検出と解決の方法について説明します。
|