Java開発の問題解決を助ける(1)
デバッグでのブレークポイント活用

サン・マイクロシステムズ
岡崎 隆之
2005/6/23

 「結果が期待と異なる」「パフォーマンスが出ない」「どうやらメモリリークしている」「コーディング規約がなかなか守られない」など、Java開発における問題点は無数にあります。これらの問題解決を効率的に行うためには、ツールや技術が必要です。本連載では、ツールを活用した問題解決法を紹介していきます。第1回は、統合開発環境(IDE)に装備されているデバッグツールを活用した問題解決を紹介しましょう。

問題はどんなところに潜んでいるのか

 「コーディングにはあまり時間がかからなかったが、デバッグが進まず徹夜で作業した」

 「膨大なログを基にデバッグをしなければいけないので精神的に参ってしまった」

 プログラム開発に参加されている方でこのような経験をされた人は多いのではないでしょうか。またさらに追い討ちを掛けるように問題が山積みになり、時間切れ・コスト超過になって低品質のままのプログラムをリリースしたり、プロジェクトが中止になってしまうことも珍しくはありません。ではなぜ問題が山積みになったり、そもそも問題解決に時間がかかってしまうのでしょうか。

問題が問題を呼ぶ

 どんなに入念にテストされたプログラムでもすべての問題をあらかじめ取り除くことはできません。順調に見えるプロジェクトでもあるとき1つ問題が発生するとその対応に追われ、そのうちに次の問題が発生……と、気が付けば問題が山積みになっているという状況はご経験の方も多いでしょう。

 問題を山積みにしないためには、問題をなるべく発生させないようにするとともに、問題が発生したとしても速やかに解決し、元のスピードで作業できることを目標にする必要があります。

問題解決スピードを上げるためには

 では問題を速やかに解決するためにはどうすればいいでしょうか。問題をうまく解決できないプログラマを見ていると次のような傾向があります。

  • 問題解決のためにどのような情報を集めればよいのかを把握していない
  • デバッグツールや、プロファイリングツールで何ができるかを知らない

 このようなプログラマはやみくもに条件を変えながらテストを繰り返していたり、System.out.printlnなどを使って変数のトレースをしているため効率が上がりません。では、問題解決のためにどのような情報を集めればよいか、各種ツールで何ができるかをご紹介します。

問題のタイプと解決の視点

 発生する問題のタイプはさまざまですが、代表的なものを挙げてみましょう。

内容が予想している値と異なる


 仕様の食い違いやコーディングミスなどによって変数に格納されている値が異なっていたり、ファイルや画面に書き出される値が異なっているというような問題が発生します。このような問題は多くの場合プログラムを実行させながら特定の変数を監視しつつ、どの時点で予想と異なる値になったかを調べる必要があります。

 このような問題はデバッガツールで変数に格納されている値をチェックする方法、変数に格納されている値をログに出力する方法を使って原因を絞り込みます。

メモリリーク/リソースリーク

 Javaのようにガーベジコレクションを装備しているプログラミング言語ではメモリリークが発生しないと思われがちですが、不要となったオブジェクトに対する参照が残っているために不要オブジェクトがガーベジコレクションの対象に含まれなくなり、メモリが解放されないメモリリークが発生します。メモリ以外にもデータベースへの接続リソースが解放されなかったり、一時ファイルが使用後も削除されないといったようなリソースリークというような問題があります。

 メモリリークについてはデバッグツールやプロファイリングツールを使用してメモリの増加傾向を調べたり、オブジェクトの参照を調べることによって原因を絞り込みます。リソースリークに関してはリソースを管理している変数をデバッガツールで監視したり、リソースの生成・削除等のイベントをログ出力して監視する方法で原因を絞り込みます。

パフォーマンス低下


 開発中には問題にならなかったパフォーマンスの問題が本番稼働後に深刻な問題となったり、単体テスト中は予定どおりのパフォーマンスを出していたプログラムが結合テストの段階でパフォーマンス上の問題が表面化するというようにパフォーマンス上の問題はプログラム全体を通して実行された段階に発見されたり、本格的な負荷が掛かることによって発見されます。

 パフォーマンスに関する問題はプロファイリングツールやデバッグツールを使用することによって原因を絞り込んだり、パフォーマンス上の問題が発生の有無を確認します。

コーディング規約が守られない

 プロジェクトでコーディング規約が定められていても、忙しさや煩わしさからコーディング規約が守られないためにプログラムのドキュメントとしての品質が低下します。このような問題に対して最近ではPMDやcheckstyleといったコーディングスタイルのチェックツールが用いられることが多くなってきました。

ツールを活用する

 問題解決を助けるためのツールはさまざまなものが考えられていますが、それらのツールの機能を把握していなかったり、使い方がよく分からないということでは問題解決のために力を発揮することができません。これらのツールをうまく自分の道具として使えるようにしておくことによって効率よく作業を行うことができます。では問題解決を助ける一般的なツールと最新の技術について以下でご紹介します。

デバッガ


 デバッガツールは次のような問題解決に威力を発揮します。

  • 内容が予想している値と異なる
  • プログラムの振る舞いが予想と異なる

 デバッガツールはJava VMと連携しプログラムを実行、一時停止、ステップ実行などを行いながら変数の内容やスレッドの活動状態を確認するというような機能を持っています。これらの機能を使用することによって、ログ出力やトレース出力のためのコードをたくさん書かなくてもプログラムの動作を詳細に知ることができます。デバッガツールはSun Java Studio Enterpriseのような統合開発環境をはじめ、ほとんどの統合開発環境に装備されており、無償で入手できるものにはNetBeansEclipseなどがあります。

プロファイラ


 プロファイラツールは次のような問題の解決に威力を発揮します。

  • パフォーマンス低下
  • メモリリークやOutOfMemoryError


 プロファイラはメソッドの実行速度やメソッドの呼び出し回数、オブジェクトのサイズなどの情報を収集するような機能を持っています。これらの機能を使用することによってパフォーマンス上の問題があるようなプログラムや、メモリリークの疑いがあるプログラムの問題個所の切り分け作業が容易になります。

 プロファイラツールはSun Java Studio Enterprise 7などのように統合開発環境に統合されているものや、最近ではNetBeans Profilerプロジェクトのように無償で提供されているものもあります。

NetBeans Profilerプロジェクトで提供されるプロファイラ(クリックすると拡大)

負荷生成ツール

 負荷生成ツールはプロファイラと組み合わせて使用することで、次のような問題の解決に威力を発揮します。

  • 高負荷時のパフォーマンス低下

 負荷生成ツールは主にWebアプリケーションに対して指定した並列度の処理を同時に行わせる負荷を生成するツールです。このような機能を使用することによってアプリケーションの負荷への耐久性をテストすることができます。またプロファイラツールと併用することにより、高負荷時にパフォーマンスのボトルネックとなっているような部分の切り分けを行うことができます。オープンソースプロジェクトではJMeterなどがあります。

静的チェックツール

 静的チェックツールは、次のような問題解決に威力を発揮します。

  • コーディングのケアレスミスによるバグ
  • コーディング規約が守られない

 静的チェックツールはソースコードやコンパイル済みのバイトコードを検査し、コーディング規約との比較を行ったり、典型的なバグのパターンからバグを発見するような機能を持っています。このようなチェックツールを使うことによってコーディングスタイルのぶれを減らしたり、ケアレスミスを発見しやすくなります。このようなタイプのツールにはソースコードを検査するPMDCheckstyle、バイトコードを検査するFindBugsなどがあります。

1/3

 INDEX

第1回 Java開発の問題解決を助ける
Page1
問題はどんなところに潜んでいるのか
問題のタイプと解決の視点
ツールを活用する
 

Page2
デバッガを使ってみよう

  Page3
ブレークポイントを設定し問題個所を絞り込む










Java Agile フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Java Agile 記事ランキング

本日 月間