連載
» 2007年08月02日 00時00分 公開

WebSphereサーバ・チューニング入門(3):IBMのWASはJVMやGCをどのように扱っているのか? (1/4)

[上野憲一郎,日本アイ・ビー・エム]

本連載は、Javaアプリケーション・サーバの1つである、IBM WebSphere Application Server(以下、WAS)についてのパフォーマンス・チューニングに関する入門記事です。チューニングといっても、実施するエンジニアによって、その方法は異なりますが、本連載はWASを前提とし、かつ80%のケースをカバーすることを目標とします(編集部注:WASのインストールから学びたい読者は、「バージョン別セットアップマニュアル一覧」のWebSphere Application Serverを参照してください)


 前回は、WASパフォーマンス・チューニングの主要項目について簡単な説明をし、パフォーマンス・チューニングの主要項目の1つである「トランスポート・チャネル・サービス」について解説しました。

 連載第3回目は、WASの基盤となるJava Virtual Machine(以下、JVM)に関するチューニングについて解説します。

WASで扱う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のJVMのハイライト

 WAS 6.1に搭載されるIBM JVMは、多くの改善がなされております。その中でもパフォーマンスに関連する項目としては、以下が挙げられます。

  • メモリ管理機能の強化
  • JIT(Just-In-Time)コンパイラの性能向上
  • ヒープメモリ・フラグメンテーションに対する改善
  • Shared Classesサポート

注意!

正確には、JVMにはJITコンパイラが含まれておりません。JITコンパイラはJRE(Java Runtime Environment)のコンポーネントです。従って本来ならば、「JVM」ではなく「JRE」と記述するべきですが、チューニング項目の多くがJVMの設定ですので、本連載ではJVMと記載することにしました。


 WAS 6.1のJVMのパフォーマンス関連項目について、少し詳しく説明した後で、パフォーマンス・チューニングについて解説することにします。

【1】メモリ管理機能の強化(GC方式の理解)

 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を理解するための2つの視点

 GCは、Javaにおけるメモリ関連のパフォーマンス・ボトルネックの大きな要因といえます。GCについては、2つの視点で観察する必要があります。

  1. GC発生頻度
    ヒープ・サイズとアロケーション・レートに依存
  2. GC時間の長さ
    ヒープ・サイズとヒープ内のオブジェクト数に依存。大ざっぱにいうと、ヒープ・サイズが小さいと、GCが頻繁に発生し、逆に、ヒープ・サイズが大きいとGC発生回数は抑えられるが、1回のGC時間が長くなる

GC方式を理解するための3つの観点

 GCの振る舞いを調整するに当たり、GC方式を理解することはとても重要です。GC方式については、大きく3つの観点で検討することにします。

  1. ヒープ領域確保の仕方
  2. GC実行時の、GCスレッドとアプリケーション・スレッド
  3. 分割(Generational)ヒープ領域 VS フラットなヒープ領域

1:ヒープ領域確保の仕方

 まずは、「どのように、ヒープに空き領域を確保するのか」という視点での説明です。この視点では、以下の2つのGCアルゴリズムについて検討します。

  • Mark&Sweep GC
  • Copying GC

Live Objectをまとめて空き領域を作る:Mark&Sweep GC

 Mark&Sweep GCでは、GCが開始されると、まず「ルートセット」からオブジェクトグラフをたどり、到達可能なオブジェクトにLive Objectとしてマークを付けます(Mark処理)。

図1 Mark処理 図1 Mark処理

 その後で、マークされていないオブジェクトは、“Dead Object”と見なされ、ヒープからふき取られます(Sweep処理)。

図2 Sweep処理後のヒープ領域 図2 Sweep処理後のヒープ領域

 Sweep処理の後、ヒープに空き領域ができますが、それらは細かく分割され点在します。そのようなヒープの状況では、トータルのヒープ空き領域が十分なサイズであったとしても、大きなオブジェクトをアロケートしようとした際には、連続した空き領域が必要になる場合があります。このような状態が発生した場合に、Live Objectをヒープの先頭の方に移動します(Compact処理)。

図3 Compact処理後のヒープ領域 図3 Compact処理後のヒープ領域

 このCompact処理は、Live Objectの移動に伴う関連する参照の更新なども行います。Compact処理は、GCごとに実施されるわけではなく、Garbage Collectorが必要と判断した際に、実施されます。

Live Objectのみを空き領域にコピー:Copying GC

 Copying GCは、ヒープ領域を2つに分割して使用します。新しく生成されるオブジェクトは、そのうちの片方の領域に割り当てられます。そして、その領域がいっぱいになり、これ以上オブジェクトを割り当てられなくなると、GCが開始されます。そして、ルートセットから参照できるLive Objectを検出(マーク)します。そして、検出したLive Objectをもう一方の領域にコピーします(Copy処理)。

図4 Copy処理(GC1回目) 図4 Copy処理(GC1回目)

 この処理を行いながら、オブジェクトの移動に伴うリファレンスデータの更新も併せて行います。コピー処理が完了すると、Live Objectのみが、一方の領域にまとめて配置された状態になります。つまり、空領域に端からオブジェクトをコピーしていくため、コピー処理後、ヒープには連続した空き領域が確保されていることになります。

図5 Copy処理後(GC1回目)のヒープ領域 図5 Copy処理後(GC1回目)のヒープ領域

 その後に生成されたオブジェクトは、先のGCでコピーされたLive Objectの後ろに割り当てられます。そして、その領域がいっぱいになると、前回の処理のコピー元とコピー先を入れ替えて、同様の処理を次のGCとして実施します。

図6 Copy処理(GC2回目) 図6 Copy処理(GC2回目)
図7 Copy処理後(GC2回目)のヒープ領域 図7 Copy処理後(GC2回目)のヒープ領域

 Copying GCは、ヒープの半分の領域のみを実際のオブジェクトの割り当てに利用しています。従って、ヒープ・メモリの利用効率という観点では効率的とはいえないでしょう。

       1|2|3|4 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。