本連載は、Javaアプリケーション・サーバの1つである、IBM WebSphere Application Server(以下、WAS)についてのパフォーマンス・チューニングに関する入門記事です。チューニングといっても、実施するエンジニアによって、その方法は異なりますが、本連載はWASを前提とし、かつ80%のケースをカバーすることを目標とします(編集部注:WASのインストールから学びたい読者は、「バージョン別セットアップマニュアル一覧」のWebSphere Application Serverを参照してください)
前回は、WASパフォーマンス・チューニングの主要項目について簡単な説明をし、パフォーマンス・チューニングの主要項目の1つである「トランスポート・チャネル・サービス」について解説しました。
連載第3回目は、WASの基盤となるJava Virtual Machine(以下、JVM)に関するチューニングについて解説します。
WASは、稼働するプラットフォームによって異なるJVM実装を使用しています。具体的には、以下のとおりです。
JVM実装 | プラットフォーム |
---|---|
Sun JVM | Solaris |
HP JVM | HP-UX |
IBM JVM | AIX、Windows、Linux(x86)、Linux(PPC)、iSeries、zSeries |
表1 プラットフォームとJVM実装の対応 |
なお、本連載では、IBM JVMを中心に取り上げていきます。Sun JVMおよびHP JVMについては、各ベンダのWebサイトを参照してください。
以下に、WASのバージョンとサポートするJVM(Java SDK)のリリースをまとめます(SolarisおよびHP-UXプラットフォームを除く)。
WASバージョン | JVMバージョン |
---|---|
6.1 | 1.5 |
6.0 | 1.4.2 |
5.1.1 | 1.4.2 |
5.1 | 1.4.1 |
5.0 | 1.3.1 |
表2 WASバージョンとJVMの対応 |
上記のとおり、WASの最新バージョンである6.1は、Java SDKのバージョン 1.5(Java SE 5.0)に対応しております。以下、WAS 6.1のJVMのチューニングに焦点を当てて解説していくことにします。
WAS 6.1に搭載されるIBM JVMは、多くの改善がなされております。その中でもパフォーマンスに関連する項目としては、以下が挙げられます。
正確には、JVMにはJITコンパイラが含まれておりません。JITコンパイラはJRE(Java Runtime Environment)のコンポーネントです。従って本来ならば、「JVM」ではなく「JRE」と記述するべきですが、チューニング項目の多くがJVMの設定ですので、本連載ではJVMと記載することにしました。
WAS 6.1のJVMのパフォーマンス関連項目について、少し詳しく説明した後で、パフォーマンス・チューニングについて解説することにします。
WAS 6.1では、ヒープ・メモリの管理機能が強化されました。2つのメモリモデルのサポートとGC(Garbage Collection)の強化です。
WAS 6.1のIBM JVMは、数種類のGC方式(GCポリシー)を提供しており、javaコマンド・オプション “-Xgcpolicy:”の設定で調整が可能です。
“-Xgcpolicy:”オプションの説明を行う前に、準備として、WAS 6.1のIBM JVMが採用しているGC方式について解説をしていきます。その後で、“-Xgcpolicy:”の設定について説明します。
GCは、Javaにおけるメモリ関連のパフォーマンス・ボトルネックの大きな要因といえます。GCについては、2つの視点で観察する必要があります。
GCの振る舞いを調整するに当たり、GC方式を理解することはとても重要です。GC方式については、大きく3つの観点で検討することにします。
まずは、「どのように、ヒープに空き領域を確保するのか」という視点での説明です。この視点では、以下の2つのGCアルゴリズムについて検討します。
Live Objectをまとめて空き領域を作る:Mark&Sweep GC
Mark&Sweep GCでは、GCが開始されると、まず「ルートセット」からオブジェクトグラフをたどり、到達可能なオブジェクトにLive Objectとしてマークを付けます(Mark処理)。
その後で、マークされていないオブジェクトは、“Dead Object”と見なされ、ヒープからふき取られます(Sweep処理)。
Sweep処理の後、ヒープに空き領域ができますが、それらは細かく分割され点在します。そのようなヒープの状況では、トータルのヒープ空き領域が十分なサイズであったとしても、大きなオブジェクトをアロケートしようとした際には、連続した空き領域が必要になる場合があります。このような状態が発生した場合に、Live Objectをヒープの先頭の方に移動します(Compact処理)。
このCompact処理は、Live Objectの移動に伴う関連する参照の更新なども行います。Compact処理は、GCごとに実施されるわけではなく、Garbage Collectorが必要と判断した際に、実施されます。
Live Objectのみを空き領域にコピー:Copying GC
Copying GCは、ヒープ領域を2つに分割して使用します。新しく生成されるオブジェクトは、そのうちの片方の領域に割り当てられます。そして、その領域がいっぱいになり、これ以上オブジェクトを割り当てられなくなると、GCが開始されます。そして、ルートセットから参照できるLive Objectを検出(マーク)します。そして、検出したLive Objectをもう一方の領域にコピーします(Copy処理)。
この処理を行いながら、オブジェクトの移動に伴うリファレンスデータの更新も併せて行います。コピー処理が完了すると、Live Objectのみが、一方の領域にまとめて配置された状態になります。つまり、空領域に端からオブジェクトをコピーしていくため、コピー処理後、ヒープには連続した空き領域が確保されていることになります。
その後に生成されたオブジェクトは、先のGCでコピーされたLive Objectの後ろに割り当てられます。そして、その領域がいっぱいになると、前回の処理のコピー元とコピー先を入れ替えて、同様の処理を次のGCとして実施します。
Copying GCは、ヒープの半分の領域のみを実際のオブジェクトの割り当てに利用しています。従って、ヒープ・メモリの利用効率という観点では効率的とはいえないでしょう。
Copyright © ITmedia, Inc. All Rights Reserved.