Java:動的プロファイリングの方法



Javaプログラムについて、ある処理を行った場合に通過するすべてのメソッドを検出したり、それにどの程度の時間がかかるのかを検出したい。

いわゆるプロファイリングというもので、それなりのツールが出ているようだ。優秀なものはそれなりに高価なようだ。

しかし、これらをプログラム自体から制御したいのである。プロファイリングする・しないのタイミングや、する・しない箇所を指定したいのである。

これを行うためのツールとしてまず挙げられるのが、AspectJである。

AspectJの使えなさ

AspectJでは、既存のJavaコードに何らかのコードを織り込んでしまい、そのコードで色々とできるようなのだ。一時期流行ったようなのだが、現在はあまり使われていないようだ。その理由として想像できることとしては、以下だ(念の為あくまで想像だ)。

  • コードに織り込んでやらせることは決まっており、AspectJのような自由度が無くてもよい。自由なコードが書ける必要は全く無い。
  • また、コンパイル時に織り込むとか実行時に織り込むとかの方法が複数あり、利用者側は混乱する。
  • 最新のEclipse(2019-09)用のプラグインが出ていない(インストールしようとすると拒否される)。利用者がいないので開発が滞っているのだろう。

特に、アノテーションを使わない方法ではAspectJ独特の言語で記述し、通常のJavaとは別にコンパイルしなければならないという点はいかにも面倒だし、Eclipse用のプラグインが動かないのは致命的である。よってAspectJは考慮外となった。

参考
* AspectJ Development Tools

独自のプロファイリングツール

AspectJ以外で最も参考になったのは以下の記事である。

これは、java.lang.instrumentという機能を使い、対象Javaプログラムのmainが実行される以前にプロファイラコードをロードし、このプロファイラコードが(通常のJavaクラス用の)クラスローダーにちょっかいを出し、バイトコードを変更してしまい、プロファイリングを行うというもののようだ。

しかし、これで気になる点としては以下だ。

  • プロファイラのコードをJarとしてまとめなければならない。
  • Java-VM起動時に上記jarを-javaagent引数で指定しなくてはいけない。

参考
* バイトコードを動的に操作 Instrumentation

動的にjavaagentをロードする方法

というのがあった。

使えるものかどうかは今後確認していく。