Skip to content

Commit 118e72d

Browse files
authored
Merge pull request #192 from javaevolved/brunoborges-lazy-stack-inspection-stackwalker
Add lazy stack inspection with StackWalker
2 parents 609c959 + 70d2ab2 commit 118e72d

4 files changed

Lines changed: 70 additions & 2 deletions

File tree

content/tooling/compact-object-headers.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ whyModernWins:
3737
support:
3838
state: "available"
3939
description: "Finalized in JDK 25 LTS (JEP 519, Sept 2025)."
40-
prev: "tooling/jfr-profiling"
40+
prev: "tooling/stack-walker"
4141
next: "tooling/built-in-http-server"
4242
related:
4343
- "tooling/jshell-prototyping"

content/tooling/jfr-profiling.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ support:
4040
state: "available"
4141
description: "Widely available since JDK 9/11 (open-sourced in 11)"
4242
prev: "tooling/multi-file-source"
43-
next: "tooling/compact-object-headers"
43+
next: "tooling/stack-walker"
4444
related:
4545
- "tooling/multi-file-source"
4646
- "tooling/jshell-prototyping"

content/tooling/stack-walker.yaml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
id: 35f7b2bd-cbf2-4b59-8553-801367e6ceee
3+
slug: "stack-walker"
4+
title: "Lazy stack inspection with StackWalker"
5+
category: "tooling"
6+
difficulty: "intermediate"
7+
jdkVersion: "9"
8+
oldLabel: "Materialized stack trace"
9+
modernLabel: "Java 9+"
10+
oldApproach: "Thread.getStackTrace()"
11+
modernApproach: "StackWalker"
12+
oldCode: |-
13+
StackTraceElement caller = Thread.currentThread()
14+
.getStackTrace()[2];
15+
String callerClass = caller.getClassName();
16+
modernCode: |-
17+
String callerClass = StackWalker.getInstance()
18+
.walk(frames -> frames.skip(1)
19+
.findFirst()
20+
.orElseThrow()
21+
.getClassName());
22+
summary: "Inspect stack frames lazily with StackWalker instead of materializing a complete stack trace."
23+
explanation: "StackWalker exposes a lazy stream of stack frames and configurable access\
24+
\ to retained class references. Code can stop once it finds the needed frame rather\
25+
\ than allocating an entire stack-trace array."
26+
whyModernWins:
27+
- icon: ""
28+
title: "Lazy traversal"
29+
desc: "Visits only the frames the operation needs."
30+
- icon: "🧩"
31+
title: "Stream-friendly"
32+
desc: "Filtering and selection use standard stream operations."
33+
- icon: "🎛"
34+
title: "Configurable"
35+
desc: "Options support class references and hidden or reflective frames."
36+
support:
37+
state: "available"
38+
description: "Widely available since JDK 9 (September 2017)"
39+
prev: "tooling/jfr-profiling"
40+
next: "tooling/compact-object-headers"
41+
related:
42+
- "tooling/jfr-profiling"
43+
- "concurrency/process-api"
44+
- "errors/helpful-npe"
45+
tags:
46+
- tooling
47+
- performance
48+
docs:
49+
- title: "StackWalker"
50+
href: "https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/StackWalker.html"
51+
- title: "Stack-Walking API (JEP 259)"
52+
href: "https://openjdk.org/jeps/259"

proof/tooling/StackWalker.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
///usr/bin/env jbang "$0" "$@" ; exit $?
2+
//JAVA 25+
3+
4+
/// Proof: stack-walker
5+
/// Source: content/tooling/stack-walker.yaml
6+
String callerClass() {
7+
return StackWalker.getInstance()
8+
.walk(frames -> frames.skip(1)
9+
.findFirst()
10+
.orElseThrow()
11+
.getClassName());
12+
}
13+
14+
void main() {
15+
IO.println(callerClass());
16+
}

0 commit comments

Comments
 (0)