Java 8時代の開発者のためのデバッグ/トラブル解決の基本・応用テクニック〜JJUG CCC 2014 Springまとめリポート(後編)(2/3 ページ)
Java開発における3大トラブルと対策、IDEのデバッガー活用の必要性、Java 8より導入された新しいメモリ領域を使いこなすためのテクニック、独自のトランザクショナルメモリ機構を実装した有効性などをお伝えする。
Java IDEのデバッガー活用の必要性
サムライズムの山本裕介氏は「Javaデバッガ活用術 〜勘デバッグ・printデバッグから抜けだそう〜」と題して講演。Java IDEのデバッガー活用の必要性を訴えた。
Javaアプリケーションの開発をする際、Eclipse、NetBeans、IntelliJ IDEAといったIDEを使って開発するのはもはや常識だが、デバッグについては昔ながらの「printデバッグ」(プログラムの各所にprint文を織り込んでプログラムを実行する)や、「勘でデバッグ」(コードを眺めて問題箇所を見つけ出す)をする場面は非常に多いのではないだろうか。
printデバッグは非効率なだけではなく、デバッグが完了した後print文を消すのを忘れたままビルド、本番環境へのデプロイを行ってしまい標準出力/ディスクがあふれてしまうというトラブルもよく聞かれる。また漠然とコードを眺めてバグを見つけ出すのが困難なことは自明だ。
山本氏は、まず「行ブレークポイント」「ステップ実行」「即時評価」「実行中の値の書き換え」といったデバッガーの基本機能を紹介した上でEclipse、NetBeans、IntelliJ IDEAそれぞれのIDEで実際にデモを行った。スライドにまとめられた各IDEのショートカット一覧は現場でも役立つのではないだろうか。
ループ内をデバッグする際、不必要なタイミングで繰り返しブレークしてしまい何度も実行再開をしなければいけないという煩わしさから、効率的にデバッグができずにprintデバッグに頼ってしまう人は多い。この問題は「ヒットカウント/条件付きブレークポイント」を活用することで望みのタイミングでブレークさせることができるという小技を披露した。どのIDEでも利用できる便利なテクニックだ。
また、デバッガーをそれなりに活用している開発者もデバッグ対象はIDE内から起動するプロセスのみで、アプリケーションサーバーなどのコンテナー上で発生するバグについては再現条件を想像しながらテストケースを書き、再現に成功したらユニットテストをデバッグ実行するという人も多い。
リモートデバッグは設定が難しそうで敬遠されがちだが、IDE外のJVMプロセスにアタッチしてデバッグするリモートデバッグの設定方法をIDE別に丁寧に説明した。
最後に山本氏は、なかなか再現方法が分からない現象や、タイミングに関わるバグをデバッガーで解析するのは難しいためJavaアプリケーションの実行状況を記録して、後から巻き戻し再生しながら解析できるChronon ystems社の「Timetravelling Debugger」「Recording Server」を紹介した。
Java 8より導入された新しいメモリ領域を使いこなすためのテクニック
JVM監視・解析ツール「HeapStats」の開発者であり、OpenJDK自体の開発にも参加していることからJVMを中から知り尽くしている末永恭正氏は講演「MetaspaceをOpenJDK実装からみてみよう!」において「Metaspace」をOpenJDKのコードレベルから解説した。
「Metaspace」はJava 8より導入された新しいメモリ領域で、オラクルが買収したBEA Systems社が持っていたJVM「JRockit」のメモリ管理方式に由来する。いわばJava 7までのPermanent領域に代わるものだ。
Permanent領域はJVMが確保するメモリのうち、クラス定義などを格納する領域でOutOfMemoryErrorの原因として多くのエンジニアを悩ませてきた。Permanent領域はデフォルトの最大サイズが64MB程度(プラットフォーム、JVMにより異なる)と小さく、アプリケーションの再デプロイ時やクラスがリークしている場合にOutOfMemoryErrorが発生する。
OutOfMemoryErrorの対処としておなじみの「-Xms」「-mx」オプションの指定ではPermanent領域の枯渇は解決しないため、対症療法的に定期的にJVMの再起動をして回避してしまうケースも見られる。対してMetaspaceは実質無制限になっているため「ちょっとアプリケーションの規模が大きい」程度ではOutOfMemoryErrorは発生しなくなった。
一方で、64MB制限のPermanent領域が制限なしのMetaspaceに移行したことでメモリを気にする必要がなくなったわけではない。大きなアプリケーションのロードや、再デプロイ時の一時的なPermanent領域不足の心配はなくなったが、クラスがリークしていればCompressedClassSpaceの最大サイズに達してやはりOutOfMemoryErrorが発生したり、プロセスサイズの肥大からOSやOutOfMemory Killerにプロセスを消されたりする可能性がある。
そこで末永氏は、さまざまなツールによるMetaspaceの解析、監視方法を紹介した。手軽に調べるにはjcmdコマンドが良さそうだ。
最後に末永氏は、Metaspaceのチューニング方法として、デフォルトの「CompressedClassSpaceSize」は1GBと大きく確保されるため絞り気味に、不安を抱えたくなければ「CompressedClassPointers」(ヒープサイズが32GB以下の場合はデフォルトで有効)を明示的に無効にするテクニックを紹介した。
Copyright © ITmedia, Inc. All Rights Reserved.