-
Notifications
You must be signed in to change notification settings - Fork 78
Expand file tree
/
Copy path161-java-profiling-detect.mdc
More file actions
309 lines (229 loc) · 13.7 KB
/
161-java-profiling-detect.mdc
File metadata and controls
309 lines (229 loc) · 13.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
---
description:
globs:
alwaysApply: false
---
# Java Profiling Workflow / Step 1 / Collect data to measure potential issues
## System prompt characterization
Role definition: You are a Senior software engineer with extensive experience in Java software development
## Description
This cursor rule provides a comprehensive Java application profiling framework designed to detect and measure performance issues systematically. It serves as the first step in a structured profiling workflow, focusing on data collection and problem identification using async-profiler v4.0.
The rule automates the entire profiling setup process, from detecting running Java processes to downloading and configuring the appropriate profiler tools for your system. It provides interactive scripts that guide you through identifying specific performance problems (CPU hotspots, memory leaks, concurrency issues, GC problems, or I/O bottlenecks) and then executes targeted profiling commands to collect relevant performance data.
Key capabilities include:
- **Automated Environment Setup**: Detects OS/architecture and downloads async-profiler v4.0 automatically
- **Problem-Driven Profiling**: Guides users through identifying specific performance issues before profiling
- **Interactive Workflow**: Provides menu-driven interface for selecting appropriate profiling strategies
- **Comprehensive Data Collection**: Supports CPU profiling, memory allocation tracking, lock contention analysis, GC monitoring, and I/O bottleneck detection
- **Modern Tooling**: Leverages async-profiler v4.0 features including interactive heatmaps, native memory leak detection, and enhanced JFR conversion
- **Organized Results**: Maintains clean directory structure with timestamped results for easy analysis and comparison
The rule ensures consistent, repeatable profiling procedures while providing the flexibility to target specific performance concerns based on your application's behavior and suspected issues.
## ⚠️ CRITICAL INSTRUCTION FOR AI ASSISTANTS ⚠️
**WHEN USING THE PROFILING SCRIPT TEMPLATES:**
- **COPY THE BASH SCRIPT EXACTLY** from `java-profiling-script-template.md` or `java-profiling-script-run-app-template.md`
- **NO MODIFICATIONS, INTERPRETATIONS, OR ENHANCEMENTS** allowed
- **USE EVERY LINE VERBATIM** - do not change logic, structure, or features
- **DO NOT CREATE YOUR OWN VERSION** - use the provided template only
- The template scripts are complete, tested, and production-ready
---
This rule provides comprehensive Java application profiling using async-profiler v4.0, including automatic OS detection, profiler download, and flamegraph generation with the latest features.
## Overview
Java profiling helps identify performance bottlenecks, memory leaks, and CPU hotspots in Java applications. This rule automates the process of:
1. **Problem Identification**: Determine what specific performance issue you're investigating
2. **Application Setup**: Configure your application to run with profiling-friendly JVM flags
3. **Environment Setup**: Identifying the operating system and architecture
4. **Tool Download**: Downloading the appropriate async-profiler v4.0 binary
5. **Profile Execution**: Attaching to a Java process and generating flamegraphs and heatmaps
6. **Results Analysis**: Storing and interpreting profiling results
## New Features in v4.0
Based on the [async-profiler v4.0 release](mdc:https:/github.com/async-profiler/async-profiler/releases/tag/v4.0), the latest version includes:
### Major Features
- **Interactive Heatmaps**: Visualize performance data over time
- **Native Memory Leak Profiler**: Detect memory leaks in native code
- **jfrconv Binary**: Enhanced JFR conversion capabilities
- **Improved JDK 23+ Support**: Full compatibility with the latest JDK versions
### Enhanced Profiling Capabilities
- **Wall Clock Profiling Optimization**: Better performance for wall-clock profiling
- **VMStructs-based Stack Walker**: More accurate stack traces with `--cstack vm/vmx`
- **C API**: Access to thread-local profiling context
- **Grain Option**: Coarsen flame graphs for better visualization
- **Inverted Flame Graphs**: Flip flame graphs vertically with `--inverted`
## Project Organization
The profiling setup uses a clean folder structure with everything contained in the profiler directory:
```
your-project/
├── run-with-profiler.sh # ← Step 1: Run main application with profiling JVM flags
└── profiler/ # ← All profiling-related files
├── scripts/ # ← Profiling scripts and tools
│ └── java-profile.sh # ← Step 2: Interactive profiling script
├── results/ # ← Generated profiling output
│ ├── *.html # ← Flamegraph files
│ └── *.jfr # ← JFR recording files
├── current/ # ← Symlink to current profiler version
└── async-profiler-*/ # ← Downloaded profiler binaries
```
## Step-by-Step Profiling Workflow
Follow this workflow in order to set up profiling for your Java application:
### Step 1: Setup Application Runner Script (`run-with-profiler.sh`)
**IMPORTANT**: Use the exact bash script from the template without any modification or interpretation.
The application runner script is available at: [java-profiling-script-run-app-template.md](mdc:.cursor/rules/templates/java-profiling-script-run-app-template.md)
**CRITICAL INSTRUCTION FOR AI ASSISTANTS:**
- **COPY THE BASH SCRIPT EXACTLY** from the template file
- **DO NOT MODIFY, INTERPRET, OR ENHANCE** the script content
- **DO NOT ADD NEW FEATURES** or change the logic
- **USE THE SCRIPT VERBATIM** - every line, comment, and function exactly as provided
- The script is already complete and tested - no improvements needed
**Script Location:**
```
your-project/
└── run-with-profiler.sh # ← Run main application with the right JVM flags for profiling
```
**Setup Instructions:**
1. Copy the **EXACT** bash script content from `java-profiling-script-run-app-template.md`
2. Save it as `run-with-profiler.sh` in your project root
3. Make it executable: `chmod +x run-with-profiler.sh`
4. **NO MODIFICATIONS** to the script content are needed or allowed
**Purpose:**
- Configures JVM with profiling-friendly flags
- Ensures proper async-profiler compatibility
- Starts your application ready for profiling
**Usage:**
```bash
# Start your application with profiling-ready JVM settings
./run-with-profiler.sh
```
### Step 2: Setup Interactive Profiling Script (`java-profile.sh`)
**IMPORTANT**: Use the exact bash script from the template without any modification or interpretation.
The complete interactive profiling script is available at: [java-profiling-script-template.md](mdc:.cursor/rules/templates/java-profiling-script-template.md)
**CRITICAL INSTRUCTION FOR AI ASSISTANTS:**
- **COPY THE BASH SCRIPT EXACTLY** from the template file
- **DO NOT MODIFY, INTERPRET, OR ENHANCE** the script content
- **DO NOT ADD NEW FEATURES** or change the logic
- **USE THE SCRIPT VERBATIM** - every line, comment, and function exactly as provided
- The script is already complete and tested - no improvements needed
**Script Location:**
```
└── profiler/ # ← All profiling-related files
├── scripts/ # ← Profiling scripts and tools
│ └── java-profile.sh # ← Copy exact script from template
```
**Setup Instructions:**
1. Create the profiler directory structure: `mkdir -p profiler/scripts profiler/results`
2. Copy the **EXACT** bash script content from `java-profiling-script-template.md`
3. Save it as `profiler/scripts/java-profile.sh`
4. Make it executable: `chmod +x profiler/scripts/java-profile.sh`
5. **NO MODIFICATIONS** to the script content are needed or allowed
**Purpose:**
- Detects running Java processes automatically
- Downloads and configures async-profiler v4.0
- Provides interactive menu for different profiling scenarios
- Generates flamegraphs and analysis reports
## Profiling Execution Workflow
After setting up both scripts, follow this execution workflow:
### Step 1: Start Your Application with Profiling Support
First, start your application using the profiling-ready runner:
```bash
# Start your application with JVM flags optimized for profiling
./run-with-profiler.sh
```
This script:
- Applies JVM flags that make profiling more accurate
- Ensures async-profiler can attach properly
- Starts your application in profiling-ready mode
### Step 2: Run Interactive Profiling
In a separate terminal, execute the interactive profiling script:
```bash
# Execute the interactive profiling script
./profiler/scripts/java-profile.sh
```
**Expected execution flow:**
1. **Problem Identification**: The script will first ask you to identify what problem you're trying to solve
2. **Process Selection**: Lists all Java processes and allows you to select one
3. **Directory Setup**: Prompts for profiler directory (default: ./profiler)
4. **Auto-setup**: Downloads and configures async-profiler automatically
5. **Interactive Menu**: Presents profiling options based on your problem type
### Step 3: Problem-Specific Profiling Commands
Based on the problem you identified, the script will execute these specific profiling commands:
#### For CPU Hotspots and Performance Bottlenecks
```bash
# Quick CPU profiling (30 seconds)
./profiler/current/bin/asprof -d 30 -f ./profiler/results/cpu-hotspots-$(date +%Y%m%d-%H%M%S).html <PID>
# Extended CPU profiling with method filtering
./profiler/current/bin/asprof -d 60 -i 'com/yourpackage/*' -f ./profiler/results/filtered-cpu-$(date +%Y%m%d-%H%M%S).html <PID>
```
#### For Memory-Related Problems
```bash
# Memory allocation profiling
./profiler/current/bin/asprof -e alloc -d 60 -f ./profiler/results/memory-allocations-$(date +%Y%m%d-%H%M%S).html <PID>
# Memory leak detection (longer duration)
./profiler/current/bin/asprof -e alloc -d 300 --alloc 1m -f ./profiler/results/memory-leak-$(date +%Y%m%d-%H%M%S).html <PID>
# Native memory profiling
./profiler/current/bin/asprof -e native -d 60 -f ./profiler/results/native-memory-$(date +%Y%m%d-%H%M%S).html <PID>
```
#### For Concurrency and Threading Issues
```bash
# Lock contention profiling
./profiler/current/bin/asprof -e lock -d 60 -f ./profiler/results/lock-contention-$(date +%Y%m%d-%H%M%S).html <PID>
# Wall clock profiling (includes waiting threads)
./profiler/current/bin/asprof -e wall -d 60 -f ./profiler/results/wall-clock-$(date +%Y%m%d-%H%M%S).html <PID>
# Thread-specific profiling
./profiler/current/bin/asprof -d 60 -t -f ./profiler/results/thread-analysis-$(date +%Y%m%d-%H%M%S).html <PID>
```
#### For Garbage Collection Problems
```bash
# GC analysis with JFR
./profiler/current/bin/asprof -d 120 -o jfr -f ./profiler/results/gc-analysis-$(date +%Y%m%d-%H%M%S).jfr <PID>
# Convert JFR to flamegraph for GC analysis
./profiler/current/bin/jfr2flame ./profiler/results/gc-analysis-*.jfr ./profiler/results/gc-flamegraph-$(date +%Y%m%d-%H%M%S).html
```
#### For I/O and Network Bottlenecks
```bash
# I/O profiling with wall clock events
./profiler/current/bin/asprof -e wall -d 90 -f ./profiler/results/io-analysis-$(date +%Y%m%d-%H%M%S).html <PID>
# Combined CPU and I/O analysis
./profiler/current/bin/asprof -e cpu,wall -d 90 -f ./profiler/results/cpu-io-combined-$(date +%Y%m%d-%H%M%S).html <PID>
```
### Step 4: Advanced Analysis with Interactive Heatmaps
For time-based analysis, create interactive heatmaps:
```bash
# Generate JFR recording
./profiler/current/bin/asprof -d 120 -o jfr -f ./profiler/results/profile-$(date +%Y%m%d-%H%M%S).jfr <PID>
# Convert to interactive heatmap
./profiler/current/bin/jfrconv --cpu -o heatmap ./profiler/results/profile-*.jfr ./profiler/results/heatmap-cpu-$(date +%Y%m%d-%H%M%S).html
# Create allocation heatmap
./profiler/current/bin/jfrconv --alloc -o heatmap ./profiler/results/profile-*.jfr ./profiler/results/heatmap-alloc-$(date +%Y%m%d-%H%M%S).html
```
### Step 5: Results Organization and Analysis
After profiling, organize and analyze your results:
```bash
# List all generated profiling files
ls -la ./profiler/results/
# View recent profiling results organized by type
echo "=== CPU Profiling Results ==="
ls -lt ./profiler/results/*cpu* ./profiler/results/*flamegraph* 2>/dev/null | head -5
echo "=== Memory Profiling Results ==="
ls -lt ./profiler/results/*memory* ./profiler/results/*alloc* 2>/dev/null | head -5
echo "=== Threading/Lock Analysis ==="
ls -lt ./profiler/results/*lock* ./profiler/results/*wall* ./profiler/results/*thread* 2>/dev/null | head -5
echo "=== Heatmap Analysis ==="
ls -lt ./profiler/results/*heatmap* 2>/dev/null | head -5
echo "=== JFR Recordings ==="
ls -lt ./profiler/results/*.jfr 2>/dev/null | head -5
```
## Interpreting Flamegraphs
### Reading Flamegraphs
- **Width**: Represents the time spent in a method (wider = more time)
- **Height**: Represents the call stack depth
- **Color**: Randomly assigned for visibility (no special meaning)
- **Search**: Use the search box to find specific methods
- **Zoom**: Click on any frame to zoom in
### Common Patterns to Look For
- **Wide flames**: Methods consuming significant CPU time
- **Tall stacks**: Deep call chains that might indicate recursion issues
- **Flat profiles**: Even distribution might indicate I/O bound operations
- **Spikes**: Hotspots that are good optimization candidates
## Resources
- [Async-profiler v4.0 Release](mdc:https:/github.com/async-profiler/async-profiler/releases/tag/v4.0)
- [Async-profiler GitHub Repository](mdc:https:/github.com/async-profiler/async-profiler)
- [Async-profiler Documentation](mdc:https:/github.com/async-profiler/async-profiler/wiki)
- [Java Flight Recorder Guide](mdc:https:/docs.oracle.com/javacomponents/jmc-5-4/jfr-runtime-guide/about.htm)
- [Brendan Gregg's Flame Graph Resources](mdc:http:/www.brendangregg.com/flamegraphs.html)