StackWalker API란?
StackWalker API는 Java 9에서 새롭게 도입된 기능으로, 기존의 StackTraceElement 기반 방식보다 뛰어난 성능을 제공합니다. 이전 버전에서는 스택 트레이스에 접근할 수 있는 방법이 매우 제한적이었고, 필요한 여부와 관계없이 전체 스택 정보를 한 번에 모두 생성해야 하는 비효율이 있었습니다.
StackWalker API는 지연(lazy) 방식으로 스택 프레임을 스트림 형태로 순회할 수 있게 해주며, 예외 발생 시 특정 스택 요소를 필터링하거나 애플리케이션의 동작을 분석하는 데 유용하게 활용됩니다.
스택 프레임의 모든 속성 출력하기
아래 예제는 StackWalker와 Option.RETAIN_CLASS_REFERENCE 옵션을 사용하여 현재 실행 중인 스택 프레임의 모든 속성(바이트코드 인덱스, 클래스 이름, 파일 이름, 메서드 이름, 네이티브 여부, 라인 번호 등)을 조회하고 출력하는 코드입니다.
예제 코드
import java.lang.StackWalker.StackFrame;
import java.util.*;
import java.util.stream.*;
import java.lang.StackWalker.Option;
public class AllAttributesTest {
public static void main(String args[]) {
System.out.println("Java 9 Stack Walker API - Print all attributes in stack frame");
StackWalker newWalker = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE);
List<StackWalker.StackFrame> stackFrames = newWalker.walk(frames -> frames.limit(1).collect(Collectors.toList()));
stackFrames.forEach(test-> {
System.out.printf("[Bytecode Index] %d%n", test.getByteCodeIndex());
System.out.printf("[Class Name] %s%n", test.getClassName());
System.out.printf("[Declaring Class] %s%n", test.getDeclaringClass());
System.out.printf("[File Name] %s%n", test.getFileName());
System.out.printf("[Method Name] %s%n", test.getMethodName());
System.out.printf("[Is Native] %b%n", test.isNativeMethod());
System.out.printf("[Line Number] %d%n", test.getLineNumber());
});
}
}실행 결과
Java 9 Stack Walker API - Print all attributes in stack frame [Bytecode Index] 21 [Class Name] AllAttributesTest [Declaring Class] class AllAttributesTest [File Name] AllAttributesTest.java [Method Name] main [Is Native] false [Line Number] 10
주요 메서드 정리
getByteCodeIndex(): 해당 스택 프레임의 바이트코드 인덱스를 반환합니다.getClassName(): 스택 프레임에 해당하는 클래스의 이진(binary) 이름을 반환합니다.getDeclaringClass(): 해당 메서드가 선언된 클래스를Class<?>객체로 반환합니다. (RETAIN_CLASS_REFERENCE옵션이 설정되어 있어야 사용 가능)getFileName(): 해당 클래스를 담고 있는 소스 파일의 이름을 반환합니다.getMethodName(): 스택 프레임이 가리키는 메서드의 이름을 반환합니다.isNativeMethod(): 해당 메서드가 네이티브 메서드인지 여부를 반환합니다.getLineNumber(): 소스 파일에서 해당 실행 지점의 라인 번호를 반환합니다.
이처럼 StackWalker API를 활용하면 불필요한 전체 스택 생성 없이 필요한 프레임만 선택적으로 조회할 수 있어, 로깅 및 디버깅 성능을 크게 개선할 수 있습니다.