大規模化・安定稼働・開発効率化…Webシステム開発・運用を乗り切るテクニック

第2回 チューニング② Java VMによるメモリ管理

この記事を読むのに必要な時間:およそ 3 分

はじめに

現在のWebシステム開発・運用で踏まえるべき新しい技術的な取り組みについて,日立のアプリケーションサーバ(APサーバ)であるCosminexus(コズミネクサス)の製品群を題材として取り上げながら解説する本連載,前回は流量制御およびDB(I/O)の最適化について触れました。

第2回は,Java仮想マシン(Java VM)によるメモリ管理が主題です。Webシステムにおいては,JavaVMのメモリ管理機能であるガベージコレクション(GC)が性能劣化を引き起こすことが知られています。ここでは日立が開発したJava VMにおけるメモリ管理技術や,日本語処理の高速化を中心に解説します。

GCの基本的なしくみと問題点

GCとは,作業領域のうち使用済みの領域を破棄して空き領域を整列させるしくみのことです。Java VMでは,自身が管理するメモリ領域(ヒープ領域)において使用されなくなった領域の破棄により空き領域を確保するため,GCを実行します。

Java VMのメモリ領域

Java VMのヒープ領域は,Javaアプリケーションが使用する「Javaヒープ」,クラスなどのメタ情報を格納する「Permヒープ」,JavaVM自身やCプログラムが使用する「Cヒープ」,スレッドごとに保持するスタック領域である「スレッドスタック」に分けられます。ほかの領域と比べてJavaヒープではトランザクション処理中のメモリ使用領域の変動が多く,GCも頻繁に発生します。

Javaヒープはさらに,「New領域」「Old領域」に大別できます。New領域は,できたてのインスタンスを配置する「Eden領域」と使用中のインスタンスを配置する「Survivor領域」で構成されます。Old領域には「業務プログラム使用領域」「J2EEサーバの使用領域」といった寿命の長いインスタンスを配置します図1)。

図1 Javaヒープ

図1 Javaヒープ

速いCopy GCと遅いFull GC

JavaヒープがNew領域とOld領域の2つの世代でメモリ管理するのに伴って,Java VMにおけるGCには,「Copy GC」「Full GC」の2種類があります。

Copy GCはNew領域を対象に使用済みのインスタンスをすべて削除する処理で,Eden領域がいっぱいになると発生します。処理の所要時間は0.01~0.7秒程度(メモリ容量が500Mバイト~1Gバイト程度の場合)とごく短く,システムへの影響は軽微です。

一方のFull GCはJava ヒープ全体を対象とし,Old 領域の業務プログラム使用領域がいっぱいになると発生します。所要時間は1 ~数十秒と長いことに加えてGC の実行中は業務処理が停止するため,頻発するとシステムの性能劣化を招いてしまいます。

Java VM ベースのシステムでパフォーマンス低下を回避するには,Full GC の発生をいかに抑止するかがカギと言えます。

アプリの変更なしにパフォーマンスを改善可能

既存のJava VM システムではFull GC の抑制が難しく,「Java では大容量メモリの扱いが難しい」というのが通説です。Java VM 自体に抑制するしくみがないため個々のシステムごとの対処を余儀なくされ,普遍的で有効な対策を見出すことは困難でした。

そのためCosminexus では,Full GCによるシステムスローダウンの課題を解決するために,これまでの運用で回避するという発想を転換し,Java VMに明示管理ヒープ領域(Eヒープ(Explicit Heap)領域)を新設して,これをGC対象外とする「Eヒープ方式」を採用することにより,Full GCレスを実現しました。

この方式では,セッションオブジェクトなど,あらかじめ長寿命であることがわかっているオブジェクトをEヒープ領域へ自動的に割り当て,解放を行うことでOld領域に配置されるオブジェクト量を削減し,Old領域の業務プログラム使用領域がいっぱいになると発生するFull GCを抑止します。いったんNew領域に割り当てられたセッションオブジェクトは,New領域からEヒープ領域へCopy GCで移動するためCopy GCの所要時間は増加するものの,この所要時間は前述のとおりごく短いため,システム全体のパフォーマンスにはほとんど影響しません図2)。

図2 Full GCレスでオンライン業務の一時停止を回避

図2 Full GCレスでオンライン業務の一時停止を回避

日立が試算した例では,従来方式で0.253 秒だった平均Copy GC 時間がE ヒープ方式では0.328 秒に30% 増加し,処理件数は54 万8,819 件から54 万5,486件へと0.61% の劣化でした。つまり,処理性能への影響は1% 未満に留まっています表1)。

表1 Copy GC時間増によるスループットの試算例

測定単位時間10:00~15:45(20,70秒)
平均Copy GC時間0.253秒/回 →0.328秒/回(30%増)
処理件数1548,819件 → 545,486件(061%劣化)
           ↓
      処理性能への影響1%未満

開発者の立場からすると,メモリ管理方式の変更によってプログラムを変更しなくてはならないのではとの懸念がありますが,Cosminexus のFull GC レス機能は,Java VM とAP サーバが連携してシームレスなE ヒープ領域化を実現しているため,プログラム側ではまったく意識する必要がありません。既存アプリの変更なしに,新しいメモリ管理方式によるパフォーマンス向上の恩恵を受けられるのです。

誤った領域削除時にも堅牢性を確保

このようにJava ヒープ内に滞留するセッションオブジェクトはE ヒープ領域へ自動的に移動されますが,DB データのキャッシュなどセッションオブジェクト以外の長寿命なオブジェクトを手動でE ヒープ領域へ配置し,不要になったら削除することもできます。

CosminexusのEヒープ方式は,誤って領域を削除してしまった場合においてもシステムの堅牢性を確保しています。たとえば,まだ使用中のデータが存在するEヒープ領域を単純に削除してしまうと,削除済み領域の参照が発生してシステムダウンという深刻な問題が生じてしまいます。そこで,Cosminexusでは領域の削除時に使用中のオブジェクトがあるとJavaヒープへ自動的に移動するため,誤って領域を削除しても問題なく動作を継続します。この技術により,あるアプリの誤ったメモリ領域削除がシステム全体に悪影響を及ぼしてしまう,ということがなくなるのです。

コメント

コメントの記入