スタックとは、本来はLIFO(後入れ先出し)方式のデータ構造のことであるが、ここでは Java VM 上にある管理領域のスタックについて書く。
スタックとは?
メソッドを呼び出すと、呼び出し情報が Java VM 上のスタックと呼ばれる領域に格納される。
この呼び出し情報のことをスタックフレームと呼び、スタックフレームの履歴のことをスタックトレースと呼ぶ。
スタックフレームは呼び出し元に制御が戻った時にスタックから破棄される。
スタックトレースの表示方法
以下は、スタックトレースを表示する方法。
Throwable() クラスのインスタンスを生成し、getStackTrace() メソッドにてスタックフレームの配列を取得している。
StackTraceElement[] _elm = new Throwable().getStackTrace(); for (StackTraceElement e : _elm) { System.out.println(e); }
検証
以下のクラスにて検証してみる。
package knowledgefort.labo.stack; class StackFrameLabo { void methodA() { this.methodB(); } void methodB() { this.methodC(); } void methodC() { this.getStackFrame(); } void getStackFrame() { StackTraceElement[] _elm = new Throwable().getStackTrace(); for (StackTraceElement e : _elm) { System.out.println(e); } return; } public static void main(String args[]) { new StackFrameLabo().methodA(); return; } }
実行した結果、標準出力に以下の内容が表示される。
knowledgefort.labo.stack.StackFrameLabo.getStackFrame(StackFrameLabo.java:13) knowledgefort.labo.stack.StackFrameLabo.methodC(StackFrameLabo.java:9) knowledgefort.labo.stack.StackFrameLabo.methodB(StackFrameLabo.java:7) knowledgefort.labo.stack.StackFrameLabo.methodA(StackFrameLabo.java:5) knowledgefort.labo.stack.StackFrameLabo.main(StackFrameLabo.java:25)
下から順に、呼び出されたメソッドの履歴が表示されることがわかる。