記憶庫

自分用のメモです。

スタックおよびスタックトレースの出力方法について

スタックとは、本来は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)

下から順に、呼び出されたメソッドの履歴が表示されることがわかる。