Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java 9 StackWalker API로 스택 프레임(StackFrame)의 모든 속성을 출력하는 방법

StackWalker API란?

StackWalker APIJava 9에서 새롭게 도입된 기능으로, 기존의 StackTraceElement 기반 방식보다 뛰어난 성능을 제공합니다. 이전 버전에서는 스택 트레이스에 접근할 수 있는 방법이 매우 제한적이었고, 필요한 여부와 관계없이 전체 스택 정보를 한 번에 모두 생성해야 하는 비효율이 있었습니다.

StackWalker API는 지연(lazy) 방식으로 스택 프레임을 스트림 형태로 순회할 수 있게 해주며, 예외 발생 시 특정 스택 요소를 필터링하거나 애플리케이션의 동작을 분석하는 데 유용하게 활용됩니다.

스택 프레임의 모든 속성 출력하기

아래 예제는 StackWalkerOption.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를 활용하면 불필요한 전체 스택 생성 없이 필요한 프레임만 선택적으로 조회할 수 있어, 로깅 및 디버깅 성능을 크게 개선할 수 있습니다.