[Java News] → [Java Performance Tuning] → [no.39] [no.40] [no.41]

Java Performance Tuning Newsletter no. 41

先月の特集記事 the Commando Pattern はエイプリルフールでした。 コードはちゃんと記事の通り動きますが、これは良い習慣とはいえないのでパターンではありません。 本当に実践してしまった奇特な方 もいるようですが、現実のプロジェクトで頻繁に使われるようなものではないので、アンチパターンでさえありません。 ジョークに気づいた方はご明察。気づかなかった方々にはお詫びを申し上げます。 しかし今回のジョークは気に入っています。 すくなくともみなさんは良い会社にお勤めのようで、このパターンの記事に関して、おそらくこのサイトにあるどの文章よりもたくさんのご意見をいただきました。 しかもこれがジョークだと気づいた方と気づかなかった方はほぼ半々でした。 少なくとも結果はそう読めましたが、もちろん読者のみなさんからもう少し控えめなエイプリルフールのお返しをいただいている可能性はありますね……

先回のジョークに受けた方なら、去年のエイプリルフールのネタ - James L. Frank氏とのインタビューでの『真の』Java誕生の裏話 も楽しんでいただけるかもしれません。

今回のニュースレターではいつもの記事、ニュース、等々をご用意しています。 さらにいつものセクションも健在です。 Kirkのまとめ では保守性と性能、SQLチューニング、Value Object、メッセージング等をカバーしています。 今号のインタビューのお相手は Hibernate の創始者 Gavin King氏 です。 今月の質問 では、アプレットのプロファイリングのやり方を扱います。

Javva The Hutt はパフォーマンスチューニングの戦いに腕をふるいます。 新作の漫画, 二重ディスパッチに関する記事、そしてもちろん、読みやすく抽出した約100件のtips を取りそろえています。

最新ニュース

Java パフォーマンスチューニング関連ニュース

ツール紹介

最近の記事

Jack Shirazi


Kirk のまとめ

The JavaRanch

保守性命! Jack と私がこのトピックを重点的に扱っているにもかかわらず、未だにニュースグループで話題に上り続けているので、このメッセージを繰り返しておく意義はあると思います。 ソフトウェア開発時の第一の目的は、保守性について関心を持つことです。 オブジェクト指向のシステムでは、これは外部の詮索から実装を隠すためにカプセル化を行うことを意味します。 Java ではクラス内のインスタンス変数を private または protected にし、加えてこれに対応する get/set メソッドを使用することでこれを実現します。 問題は、この実装が性能に及ぼす影響です。 牧場のメンバーがマイクロベンチマークで示したように、数十億回のアクセスでも get/set メソッドと直接の読み書きの差は計測不能でした。 ここまでわかっていて、なぜあえてメンテナンスを困難にするリスクを犯してまで、直接インスタンス変数にアクセスする人がいるのか、私には全くわかりません! それでも性能がいいからと言う理由で、このテクニックが使われているのをしょっちゅう目にします。 ここでの教訓は、「推測するな、計測せよ」です。

次の議論での最初の質問は、複数の小さな SQL クエリを一つにまとめるべきか否か、というものでした。 質問の前提は、クエリが絡むとアプリケーションの性能が落ちるということです。 牧場の客から、データベース性能を向上させるためのこつがいくつか与えられました。 そのなかにはストアドプロシージャを使う、DB設計を確認する、といった定番の指摘もありました。 バーテンダーは興味深い質問をたずねました。 一言で言うと、なぜそれがわかったのか? 言い方を変えると、データベースが問題の大元だとどうやってわかったのか? 答えは、「計測しないかぎり、わからない」です。 ここで IronEye のようなツールが役に立ちます。 また、データベースベンダーは性能問題の分析に非常に役立つ統計情報を持っています。 このケースでは、ネットワークに問題があるかどうかさえはっきりしていませんでした。 正しく計測を行えば、問題の原因を特定できます。 問題が正しく分析されたら、それを修正する方法もすぐに明らかになります。 教訓は「2回計測して、1回目は捨てよ」です。

最後にご紹介する議論は、データ転送オブジェクト (data transfer object) に関するものでした。 一般的には DTO と呼ばれ、最近では Martin Fowler氏が(当初 Smalltalk コミュニティによって名付けられた通り)Value Object として再提唱しています。 議論自体は短いもので、シリアライゼーションについていささか考慮の足りない感がありましたが、その辺は脇に置いて本題にはいります。 DTO、VO、呼び名は好きずきですが、これは2つの単純な理由により、きわめて有害なのです。 まず、これらはカプセル化を破るため、保守コストを増大させます。 次に、これらは並行的階層として働くため、開発・保守のコストを増大させるのです。

DTO は2つの問題を発端にして脚光を浴びました。 ネットワーク上で受け渡す巨大なオブジェクトグラフを削る方法がわからないこと、そして (EJBのように) 受け側でこれを格納する適切なコンテナがないということです。 後者は、今まで通りふつうに java のオブジェクトを使えば解決です。 前者の解決策はそれほど簡単ではありません。 削らなくてはいけないオブジェクトグラフがあるなら、シリアライゼーションのカスタマイズで行うのがベストでしょう。 別の選択肢として、オブジェクトの配布を小さめの塊(チャンク)で行える VM を使う手もあります。 残念ながら、このオプションをサポートする私が知る限り唯一の VM はすでに現存していません。 このような状況でも、設計を見直して、これらの大きなオブジェクトグラフ(と、それが表すリレーションシップ)が本当に必要か見極めることで、いくらかは効用を得られるでしょう。 モデルを縮小することで、より多くの効用を得られる可能性は大いにあります。 うまく行かなければ、いつでも DTO に戻せばいいことです。 少なくとも、回転ドアアンチパターンに陥るよりましなのは明らかです。

The Server Side

The Server Side に目を向けると、JBoss 3.0 の MDB(message-driven beans) 性能の低さについての対話がみつかります。 最初の投稿は、1秒あたり 2000メッセージを送ると性能が遅いというものでした。 こういう、問題がはっきりしない投稿にいいアドバイスを返すのは非常に難しいものです。 投稿の趣旨は point-to-point メッセージングに関するもののようでした。 問題は、JBoss のメッセージングが秒速 2000メッセージも処理できるのか、ということです。 この手の質問をするときには、ハードウェアが JBoss に 2000件のメッセージをちゃんと送れるのかどうか、質問者が意識しないといけません。 この速度ではネットワークが飽和してもおかしくありません。 たとえば、10メガビット/秒のネットワークだとして、そのネットワークの正常な数値は 4メガビット/秒くらいに見えることでしょう(ネットワーク帯域は片方向のピーク値であり、コリジョン管理を行う多くの種類のネットワーク通信では通常達成されないものです。有効な帯域幅の平均値は容易にピーク値の 1/3 になりうるのです)。 計算してみると、4メガビットは 4194304ビット/秒、あるいは 524288バイト/秒になります。 これを秒間メッセージ数 (2000) で割ると、1件あたり 262バイトという数字が得られます。 言い換えると、メッセージが 262バイトより大きく、それが1秒間に 2000件以上ある場合、ネットワークが飽和します。 設定は変えられるとはいえ、パケットサイズが 512バイトになっていることは珍しくない点にも注意すべきです。 これを現実に置き換えると、大きさが 1パケット分であるメッセージを 1秒間に最大で 1000件サーバーに送れるということです。 メッセージがこれより大きくなれば、問題はひたすら悪化していくでしょう。 ありがたいことに、ほとんどの内部ネットワークは 100メガビット以上の転送レートをサポートします。 しかし 100メガビットであっても、2620バイトあればネットワークは飽和するのです(条件が同じの場合という前提ですが、検証なしに鵜呑みにするのは非常に危険です)。 ネットワークが飽和したと断定することはできるのでしょうか? 残念ながらそう断定するに足るだけの情報がないので、それが無理なことは明らかです。 ただ情報があるなら、断定するための手段は間違いなくあります。

性能に効く JVM引数に関する議論で、私はついに「高速化ボタンはどこにあるんですか?」に相当する投稿を見つけました。 私も高速化ボタンなんてものがあればと願わずにいられませんが、そんなものはないのです。 いやちょっと待って、そんなものがあったらうちの教育コースに来る人がいなくなるから、それはそれで悪いことじゃないような。 冗談はともかく、チューニングとはターゲットを設定して、目標(スループットとレスポンスタイムを決めて、その後で計測を行い、どの JVM 設定が目標達成に役立つかを決める手助けとすることなのです。

JavaGaming.org

java gaming での議論をレポートしたいのですが、残念ながら今月はなにも新しい話がありません。 参加者のみなさんは最近の集会のあとで、お互いのゲームを試すのに忙しい模様です。

Kirk Pepperdine.


ジャヴァ・ザ・ハットの日記

1月28日
人間対機械。 オレの悪徳と巧妙さ対、結果を考えずにすべての命令を実行する、奴隷的で邪悪で疑問を抱かない従順さ。 そう、今オレは再びパフォーマンスチューニングを行うべく袖をまくっているのだ。 オレはあるパートナー企業のアプリケーションの性能テストを行うために、そこのテスト機へのアクセスを与えられた。 その機械には "bob" という物騒な名前がついていた。 当然、オレはそいつのキャラにふさわしい名前に即刻リネームしてやった。 「ベールゼブブ(Beelzebub:魔神の君主)」と。 最初の遭遇で、この先の展開をなんとなく感じることができた。 オレは行儀良く "Hello Beelzebub" などと自己紹介した。 答えは "Hello not found" と実にいかめしいものだった。 こりゃうまくいきそうにないな。

次の手だ。オレは手製の負荷テストスクリプトを仕掛けて、サーバサイドでの監視を追加した。 ヤツは身もだえして、ありうる限りの技を使ってオレのテストをクラッシュしやがった。 設定パラメータ、スクリプトの調整、xml ファイルの変更、一つ一ついじっていって、じりじりとベールゼブブの抵抗を屈服させていった。 そしてついに、鎖で固められて服従を強いられた、この非情で邪悪なるものをオレは完全に支配したのだった。 そしていま、オレの毎日の "Hello Beelzebub" という挨拶は従順な "Welcome Master" という答えに迎えられるようになった。

しかしもちろん、これは戦いのほんの序章にすぎず、まだ勝利が得られていたわけではなかった。 ベールゼブブは従順を装っていただけだった。 実はヤツの抵抗はアプリケーション層に移っていたのだ。 いま、オペレーティングシステムとアプリケーションは同盟を結んで、ヤツらを制圧しようというオレの努力に抵抗していた。 おかげでオレの仕事はよけいに難しくなった。 メモリのボトルネックはCPUのボトルネックであるかのようにふるまった。 ネットワークのボトルネックは競合問題に見せかけた。 競合問題は、世界最高の暗殺者にねらわれているかのごとく姿を隠していた。 改善したとおぼしき状況ではガベージコレクションがふらついて回り、調べてみると長期的なメモリ管理の問題がオレを不意打ちしようと待ちかまえているのを見つける羽目になった。 分析に次ぐ分析の中で、全力を尽くしてベールゼブブは生成されるデータから決定的な情報を隠し続けた。 あっちの設定変更、こっちのコード書き換え、とやりながら、ゆっくりとではあるがようやくオレは前進し始めた。 とらえどころのなかった標的にピントが合い始め、捕捉できるように見えてきたのだ。 今一度、人類は機械に対して優位を確保しようとしていた。 ニール・アームストロングの言葉を言い換えれば、「人類にとっては小さな一歩だが、ある機械の抵抗が虫ケラのようにつぶされた」のだ。 いや言い換えにもなってない、というか台無しにしただけっぽいけど、言いたいことはわかるだろ。

過去何年にもわたる人工知能の研究が有益だったことはオレにもわかってる。 感覚を持っているオペレーティングシステムは存在する。 馬鹿で冷酷だが、感覚はあるんだ。 でなければ、一番都合の悪いときにタイミング良くクラッシュするような芸当がどうしてヤツらにできるんだ? システムに変更を加えて、ちょっと注意をそらしているときに、その設定がゆっくりともとの設定に戻っていくのはなぜだ? ムキになってるわけじゃないが言わせてくれ。 「テメェの負けだベールゼブブ! ゲラゲラ」

じゃ、またな

Javva The Hutt.


インタビュー: Hibernate 創始者 Gavin King 氏

今月はオープンソースのオブジェクト/リレーショナルマッピングプロジェクトである Hibernate の創始者Gavin King 氏にお話をうかがうことができました。

JPT: ご自分のことや活動について簡単に教えてください。

私は Java 用オブジェクト/リレーショナルマッピングソリューションである Hibernate プロジェクトの創始者です。 私は最近 JBoss Inc. に参加しました、Hibernate の開発にフルタイムで集中し、サポート、教育、コンサルティングサービス周辺でビジネスを開拓するためです。 また、JCP プロセスを通じて、永続化に関する私たちのアイディアを Java の標準に盛り込もうと鋭意努力しています。 つい先日 Christian Bauer 氏とともに "Hibernate in Action" という本を書き終えたところです。

JPT: Hibernate を作ろうと思ったのはなぜですか。

Hibernate は Entity Beans の有名な問題に対する解決策として設計されました。 私は Cirrus Technologies というオーストラリアのかいしゃでJ2EEアプリケーションを開発していたのですが、自分の生産性の低さと、オブジェクトモデリングのテクニックを業務問題に適用できないことに非常にいらだちました。 顧客の問題のことを考えるよりも、永続化について考えることに多くの時間を割く羽目に陥っていました。 こんなことはどう見ても間違っています。

JPT: 今 Hibernate が大いに注目を集めているなかで、JBoss に加わった理由はなんですか?

Hibernate のような適用範囲の広く、サポートすべきユーザー数が多大なプロジェクトを自分の余暇だけで進めるのは単純に不可能です。 プロジェクトの参加者がボランティアだけでは、プロジェクトの達しうる規模や商用の製品相手に発揮できる競争力は限られます。 これはオープンソースのボランティア主義の重要性を損なうものではありません。 まさしくこれはオープンソースの基本的な概念であって、オープンソースモデルをとても興味深いものにする要素のひとつです。 しかしある時点で、ライセンスを売るような人々と本気で競争したいと思うことがあります。 そしてそのとき、二つのことが必要になります。 一つ目は自分が集中できること、そしてオープンソースプロジェクトを最優先にできることです。 二つ目は、自分のユーザーに対して彼らが商用ソフトウェアに期待するものの一部を提供できなくてはいけない、ということです。 ここではたとえば 24時間週 7日のサポートや、教育コースのことをさしています。 さらに、社外に出てコンファレンスなどのイベントで人々と話したりできる必要があります。 仕事としてですよ!

で、なぜ JBoss か、ですね? そうですね。 JBoss は自社がサービスを販売するオープンソースソフトウェアの開発に実際に給料を払う、ほぼ唯一の会社です。 世間の他のオープンソース企業はデュアルライセンスや、実際は自分の手で作っていないソフトをパッケージにしたもの、あるいはそれに対するサービスを売ることで利益を得ようとしています。 その意味では、JBoss は私がさっき言ったようなことをして生計を立てられる事実上世界で唯一の場所なのです。 さらに大事なことは、JBoss はすばらしい職場だということです。 これほどダイナミックな企業文化はこれまで見たことがありません。 たぶん、これはアメリカの起業家的ビジネス文化と、オープンソースコミュニティで見られる半構造的な開発アプローチの混交の結果だと思います。 あなたが革新的なテクノロジーを打ちたてようとしているなら、これは本当にすばらしいことです。

JPT: Hibernate と、TopLink やその他の JDO 実装との違いはなんですか?

Hibernate は商用の競合製品と比べて同等、多くの場合はより高機能なオープンソースソリューションです。 フリーであることにより、私たちは多くのユーザーを引きつけてきました。 多くのユーザーを持つことで、私たちは彼らが本当に必要としている機能がなんなのかということを理解することができました。 大きな違いは、私たちのコミュニティ主導の開発モデルにあります。

一部の商用製品は確かに高価なのですが、私たちは Hibernate を「安価な」代替品だとは考えていません。 むしろ、ユーザーはより彼らの要求に沿っている、より安定している、サポートが良い、といった理由でHibernate を使っていると考えています。 オープンソースであることはドキュメントがおざなりであることのいいわけにはなりません。 私たちは OSS によって、ユーザーは望みのものを手に入れられる、つまり商業ベンダーがうまくやれることはすべて同じくらいうまくこなし、さらに彼らのできないたくさんのこともやれる(たとえばソースを公開するとか)、ということを証明しようとしています。

JPT: このプロジェクトに参加してから、O/R マッピングに関するあなたの従来の考えは大きく変わりましたか?

この道に進んだとき、私は O/R マッピングに関してほとんど知識がなく、データベースに関してはさらに無知でした。 私の最初の仕事のひとつは、SQL を正しく学ぶために外に出て本を買うことでした。 私の諸問題に対する理解はすべて、私たちのユーザーが過去2年間に教えてくれたことから来ています。

JPT: Hibernate を使うべき理由、場所、時期とはどのようなものですか?

オブジェクト指向ドメインモデルを使用する、小規模でないアプリケーションをお持ちなら、Hibernate を使うべきだと思います(小規模でない、という言葉の定義は一定ではありませんが、個人的には 10テーブル程度のアプリケーションには Hibernate は向かないと考えています)。 すべてのアプリケーションがドメインモデルを必要とするわけではないので、O/R マッピングがすべてのアプリケーションにとって必要とはなりません。 しかしあなたのアプリケーションが単にテーブルデータを web ページに表示するのではなく、たくさんのビジネスロジックを処理するなら、ドメインモデルはたいていの場合良いものです。

Hibernate は何百ものテーブルと複雑な相互関係を持つ、非常に複雑なデータモデルを持つアプリケーションで効果を発揮し始めます。 この種のアプリケーションでは、Hibernate はコーディングの労力を大幅に(ものによっては 25%も)削減し、結果として手で組んだ JDBC コードよりも高性能なアプリケーションができあがります。 これが可能になるのは、ある種の性能最適化(キャッシュ、外部結合フェッチ、トランザクショナル遅延書き込み等)を手でコーディングするのは非常に難しいためです。

JPT: でも、この種の小さくてアトミックな永続化フレームワークは、O/R マッピングは簡単な問題だという発想から出てくるものだと言うことはお互いにわかっていると思います。 率直に言えば、「小規模である限りは」これは簡単な問題です。 この規模を拡大しようとしたときに限って問題が表面化します。 Hibernate にはこの傾向を解消するような効果があると思われますか?

私がこの取り組みを始めたときは、求められているのは単純なソリューションだと考えていました (「J2EE は複雑すぎる」という意見はよく聞きますから、これは理にかなっているようです)。 実際には O/R マッピングは潜在的な意味で難しい問題でした。 一度泥臭い作業に手を染めるまでは、外面だけはいつも簡単に見えるものなのです。 だからまともな永続化ソリューションが実際に世に現れるまでに、信じがたいほど長い時間がかかったのです。 かなり早い段階で、私は「シンプル」という切り口ではこの問題を扱いきれないと気づきました。 そこで今度は恥知らずなまでに複雑なソリューションができあがりました。 しかし、たぶん必要以上に複雑ではないと思います。 そして現実には、これが実際のユーザの人生をシンプルにする最良の方法だったのです。

私たちの本では、"オブジェクト/リレーショナルのミスマッチ" が実のところ何なのかを徹底的に追求しようとしました。 多くの人がその存在を認めているけれども、それを本当に定義しようとした人は多くはないからです。 書籍の中で私たちが述べている内容の一部には驚かれる方もいるかも知れません。

JPT: アプリケーションの「中間層」で動くコンポーネントは、定型的な性能要件を持たない傾向がある、という意味ではトリッキーなものです。 Hibernate の性能要件の設定にはどのように取り組んでおられますか?

そうですね。性能をはかる一見わかりやすい方法は考えてあります。 Hibernate を同等の JDBC コードと比較することはできますね。 ところで、このテストは誤解を招きかねないことがわかりました。 一部の重要な性能最適化(たとえばトランザクションレベルのキャッシュ)を行うと、誰もがよく書くような小さなベンチマークでは、実際には性能が落ちるのです。 これは何よりも、ベンチマークの小ささ自体の問題なのです。

私が今までに見てきたどのベンチマークも、大規模な事例の中で O/R マッピングの性能を実際に左右するような問題を再現するにはとても至っていませんでした。 最大の問題は、私たちが「グラフナビゲーション問題」と呼んでいるものから発生します。 オブジェクト指向アプリケーションが使用するデータアクセスのパターンが、リレーショナルデータのアクセス手法として根本的に非効率である、というものです。 そこで、かわりに私たちは定型的でない性能測定の手法に大きく頼っています。 ソフトを公開し、ユーザーのみなさんに問題を探してもらうのです。 問題が起きたらきわめて迅速に修正する、という用意がある限り、これはまったく問題ありません。 私たちが直面した性能問題の多くは、コードの最適化よりも新機能の追加で解決されてきました。 実際には、等価な SQL直接実行/JDBC と比較しても、Hibernate 自身のオーバーヘッドはいつも無視できるほど小さなものだとわかりました。 なので、私たちはより効率的な SQL/JDBC を生成する方に力を注ぎます。 ボトルネックはいつもデータベース自身なのです。

JPT: 製品がどのように使われるか、ということも性能指標の一つといえます。 Hibernate はあなたの期待通りに利用されていますか? 良い意味で驚くような利用モデルはありますか? こういう使い方はしないほうがいい、というようなモデルについてお話しいただけますか?

問題を起こしやすい利用モデルが二つあります。 ひとつは、実際には適切でないところに O/R マッピングを適用しようとすることです。 O/R マッピング - そしてまさしく Java - が不適切であるような例の代表は、データを一括処理するような場合です。 何百万行もデータベースから取り出し、JVM に格納し、一行ずつ更新していくような処理は効率的になりようがないのです。 こうした用途にJavaを使ってはいけません。 ストアドプロシージャを使いましょう。

二つ目の問題は、どちらかといえば文化的なものです。 開発者の中には、SQL やリレーショナルデータベースを扱うのが苦手なために、Hibernate のようなツールを使い始める人がいます。 Hibernate を使う理由としては、これは全くの間違いだと私たちは断言します。 Hibernate を使う前に、SQL や JDBC には精通しているべきです。 Hibernate は JDBC の上で成り立っているのであって、これを置き換えるものではありません。 ですから Hibernate を呼び出すビジネスロジックを作るときは、最終的にどのようなデータベース呼び出しが生成されるのか正確に監視するべきです。 そうでなければ、裏で何が起きているのかまったくわからないために、いとも簡単に性能の悪いアプリケーションを作ってしまうことになります。 これは余分な抽象化によるコストです。 その一方で、こうしたアプローチの結果として生じる性能障害を後から直すのは、たいがいの場合非常に簡単なことです。 これこそ余分な抽象化の利点であり、欠点を補ってあまりあるものです。 しかし開発工程のすべての段階でデータベースに注意を払っておけば、労力を無駄にせずにすむでしょうね。

JPT: 性能測定ツールのスイートはどのように定義したんですか?

私たちはいくつか標準的な性能テストを用意していて、私が定期的に実施しています。 どれも Hibernate を手製の SQL/JDBC と比較するものです。 ただし前にも言いましたが、これらのテストは実運用にはまるで役に立ちません。 私がこれまでにやってきたスケーラビリティのテストはとても形式はずれなもので、Hibernate よりも先にデータベースが音を上げるという私の予想が必ず証明されています。 今は JBoss を通じて本物のストレステスト環境を利用できるので、Christian Bauer 氏がもう少し形式だったベンチマークを作っています。 これには前にお話ししたような大規模用途向けのテストが含まれる予定です。

私たちは他の O/R マッピングソリューションとの比較テストのために、これらのベンチマークを公開することを考えています(反証も示さずに既存のベンチマークを批判するのは正しいこととは思われないでしょうから)。 しかしこれに関して私は確信がありません。 他のグループがずるをするのを止められるとは思わないし - それにベンチマークに必ずついてまわるもろもろの言い争いには正直関わりたくないのです。 ベンチマークは誠実に使われるより、ミスリードのために使われることの方がはるかに多いのです。

JPT:(blogなど)Web上のコメントのほとんどはとても肯定的ですが、一部にはキャッシュ機能をうまく利用していないという意見もあります。これについてどうお考えですか?

何に対してのコメントか趣旨をとりかねますが。 Hibernate はきわめて複雑で粒度の高い2層キャッシュ機構を備えています。 (2次)プロセスを有効化・無効化したり、特定のクラスやコレクションロールに対してキャッシュ層をクラスタ化する事もできます。 EHCache, JBossCache, SwarmCFache, Tangosol Coherence Cache など、プラグイン可能なキャッシュ実装をサポートしています。 粒度の高いクエリの結果セットのキャッシュもあります。 複雑さと引き替えにこれら全ての柔軟な機構が得られています。 これは新しいユーザーにはややこしく見えるかも知れません。 そのため、キャッシュ機構は私たちの教育コースでも重点的にカバーする項目の一つに入っています。

JPT: 最近の blog の記事で、Hibernate からファイナライゼーションを削除することの効果についてコメントされていましたが、この変更を行ったきっかけは何ですか?  Hibernate の利用者が受けうる影響はどのようなものですか?

実のところもう何週間も前のことなので、私がそこにたどり着いた経緯は正確には覚えていません。 あり得ないと思っていた場所に性能問題の原因があった、という古典的なケースでした。 悪いことに現象はガベージコレクターのスレッド内で起きていたので、OptimizeIt でも原因がはっきりしなかったのです! さてみなさんに注意しておきたいのですが、実際の運用では、通常なら良好に動くアプリケーションがこの手の性能問題によって足を引っ張られる、といった状況は極めて考えにくいことです。 確かに Java の性能に関する神話にはこの手のものが多いのですが。 ときどき使っている文字列結合の是非を議論するのに費やす時間と労力は、非効率なデータアクセスなど、本当に重要な性能問題を追求するためにもっと有効に使えるはずなのです。 そしてこの問題はまさにそういう種類のものでした。

問題は私がファイナライザを使っていて、その中でアプリケーションが Hibernate のセッションをちゃんと閉じたかどうか確認し、そうでなければログにメッセージを書き出すようにしていたことでした。 運の悪いことに、このファイナライザが存在するだけで、そのオブジェクトに関連するメモリはまるまる2サイクル分のガベージコレクションが走るまで解放されないことを意味していたのです。 一部の非常に小さなトランザクションで、これが驚くほど大きなオーバーヘッドを起こしていることを突き止めました。 しかし大局的に見れば、アプリケーションがちゃんとセッションを閉じていなければ、ずっと大きな性能問題が起きていたはずです。 だとすれば、このファイナライザの「コスト」は、代わりに得られた効用に見合うものだったのかも知れません。 繰り返しになりますが、小規模なテストの結果には注意しなくてはいけません。 小さいコードでは、ほぼどんなときでも「十分な」性能が出るからです。

(インタビュー終)


今月の質問:アプレットのプロファイリング

アプレットをプロファイリングする手段はいくつかあります。

  1. 各種メソッド呼び出し時に時間を計るコードを直接追加し、この(あなたの設計に沿って出力された)データを解析して時間のかかっている部分を見つける。 ほかに手段がない場合以外は、これはお勧めできません。
  2. appletviewer (JDKの "bin" ディレクトリにあるはずです)で実行し、-J 引数を使ってプロファイラのパラメータを渡す。 たとえば、 appletviewer -J-Xrunhprof:cpu=samples myappletpage.html または appletviewer -J-Xprof myappletpage.html.
  3. Sun のアプレットビューアクラス (sun.applet.AppletViewer) を使って、通常の VM と、普段使っている任意のプロファイラで実行する。 たとえば、 java -Xrunhprof:cpu=samples sun.applet.AppletViewer myappletpage.html または java -Xprof sun.applet.AppletViewer myappletpage.html
  4. 任意のブラウザでアプレットを実行し、Java プラグインや組み込み JVM に任意のプロファイラを接続できるようにする。 これを実践するのはおそらく困難なうえ、接続できるプロファイラとブラウザの組み合わせも限られます。 実現方法についてはプロファイラのベンダに確認しましょう。 しかし FAQ になっていることもありうるので、簡単な手順で実現できるかも知れません。

技術論から離れると、アプレットのプロファイリングはなんら特殊なものではありません。 そのコードは通常の Java プログラムと同じように最適化する必要があります。 それに加えてアプレットのダウンロードと開始にかかる時間の問題もあります。 つまり、アプレットとすべての関連するリソースを圧縮した jarファイルに入れておくべきだということです。 しかしもっと好ましいのは、アプレットがほぼリソースなし、かつ最小限のクラスファイルで(つまりできうる限り速く)起動し、ユーザの目を引く、あるいは楽しませている間に、それ以後に必要なリソースを全部ダウンロードすることです。

The JavaPerformanceTuning.com team


Tips(技法・裏技)

http://otn.oracle.com/tech/java/architect/mwa_week8.html
巨大なデータベース
(最終更新日 2004年3月、追記 2004年4月29日、 著者 Daniel Liu、出典 Oracle). Tips:

http://www.ddj.com/documents/s=9089/ddj0404f/0404f.htm
遺伝的アルゴリズム&最適解
(最終更新日 2004年4月、追記2004年4月29日、著者 Michael Larson、出典 Dr. Dobb's Journal). Tips:

http://www.devx.com/wireless/Article/20292
移植性の無いモバイルJavaアプリケーションの9つの誤り
(最終更新日 2004年3月、追記 2004年4月29日、著者 Simon Keogh、出典 devX). Tips:

http://www-106.ibm.com/developerworks/library/j-jtp01274.html
ガベージコレクタに優しいクラスの書き方
(最終更新日 2004年1月、追記 2004年4月29日、著者 Brian Goetz、出典 IBM). Tips:

http://www.sys-con.com/WebSphere/article.cfm?id=470
WebSphere 5.0 におけるトランザクション
(最終更新日 2004年2月、追記 2004年4月29日、著者 Kyle Brown、出典 Websphere Journal). Tips:

http://www-106.ibm.com/developerworks/library/ws-best9/index.html
Web サービスのパフォーマンスに関する考察, Part 1
(最終更新日 2004年2月, 追記 2004年4月29日, 著者 Holt Adams, 発行者 IBM). Tips:

http://www-106.ibm.com/developerworks/library/ws-best9/index.html
Web サービスのパフォーマンスに関する考察, Part 2
(最終更新日 2004年2月, 追記 2004年4月29日, 著者 Holt Adams, 発行者 IBM). Tips:

http://today.java.net/pub/a/today/2004/03/01/jsr166.html
Concurrency Utilities
(Page last updated March 2004, Added 2004-04-29, Author Brian Goetz, Publisher java.net). Tips:

http://dev2dev.bea.com/products/wlplatform81/articles/thread_dumps.jsp
スレッドダンプ
(最終更新 2004/1, 追記2004-04-29, 著者Alexandre Rafalovitch, 出典 BEA). Tips:

http://www.adtmag.com/article.asp?id=8931
Rory Herriman、リモートからのパフォーマンス管理を語る
(最終更新2004/2, 追記 2004-04-29, 著者 Programmers Report スタッフ, 出典 ADTmag). Tips:

http://otn.oracle.com/tech/java/architect/mwa_week7.html
多層環境のチューニング
(最終更新2004/3, 追記2004-04-29, 著者Allan Edwards, 出典 Oracle). Tips:

http://www.onjava.com/pub/a/onjava/2004/03/10/quartz.html?page=1
Java でのジョブスケジューリング
(最終更新2004/3, 追記2004-04-29, 著者 Dejan Bosanac , 出典 OnJava). Tips:

Jack Shirazi


Last Updated: 2004-6-21
Transcopyright 2001-2004 JavaPerformanceTuning translation team. All Rights Reserved.
contributors: Tsuyoshi FUKUI, Akky AKIMOTO Hiroki, Yasunori Taniike, Nobuyuki Hirashima, Yoshie HAMANA, Yukio Andoh
Copyright © 2000-2004 Jack Shirazi. All Rights Reserved.
Original URL: http://www.JavaPerformanceTuning.com/newsletter041.shtml
URL: http://javanews.jp/javap/newsletter041.html
Japanese version maintained by Yukio Andoh - andoh@javanews.jp