Chapter 1: Introduction to JVMTI
- 1.1 Real-World Use Cases
- 1.2 Evolution: JVMPI, JVMDI → JVMTI
- 1.3 JVMTI vs Other Tooling Interfaces
- 1.4 Requirements and Environment Setup
- 1.5 A Note on C vs C++ Calling Convention
Chapter 2: Anatomy of a JVMTI Agent
- 2.1 What is a JVMTI Agent?
- 2.2 Lifecycle Entry Points
- 2.3 Error Handling: The Foundation
- 2.4 Minimum Viable Agent
- 2.5 Parsing Agent Options
- 2.6 Companion Java Application
- 2.7 Compiling with CMake
- 2.8 Running the Agent
- 2.9 Optional: File-Based Logging
- 2.10 Troubleshooting Tips
- 2.11 What’s Next?
Chapter 3: Capabilities and Events in JVMTI
- 3.1 Understanding JVMTI Capabilities
- 3.2 The Event Model
- 3.3 Event Categories
- 3.4 Writing Event Handlers
- 3.5 Controlling Events at Runtime
- 3.6 Complete Example: Thread and Method Tracker
- 3.7 Best Practices for Event Handling
- 3.8 Troubleshooting
- 3.9 What’s Next?
Chapter 4: Inspecting Threads, Stacks, and Methods
- 4.1 Enumerating All Threads
- 4.2 Walking the Stack
- 4.3 Retrieving Method Details
- 4.4 Inspecting Local Variables
- 4.5 Complete Example: Thread Dump Agent
- 4.6 Best Practices
- 4.7 Troubleshooting
- 4.8 What’s Next?
Chapter 5: Heap Inspection and Object Tagging
- 5.1 Required Capabilities
- 5.2 Iterating Over Heap Objects
- 5.3 Object Tagging
- 5.4 Getting Object Sizes
- 5.5 Monitoring Object Allocations
- 5.6 Heap Walking Safety
- 5.7 Combining Heap and Stack Data
- 5.8 Complete Example: Heap Histogram Agent
- 5.9 Best Practices
- 5.10 Troubleshooting
- 5.11 What’s Next?
Chapter 6: Class Transformation and Bytecode Instrumentation
- 6.1 How Class Transformation Works
- 6.2 The
ClassFileLoadHookCallback - 6.3 Filtering Classes
- 6.4 Modifying Bytecode
- 6.5 Bytecode Instrumentation Strategies
- 6.6 Retransformation vs. Redefinition
- 6.7 Complete Example: Class Load Monitor
- 6.8 Best Practices
- 6.9 Troubleshooting
- 6.10 What’s Next?
Chapter 7: Interacting with the JVM Runtime
- 7.1 Reading System Properties
- 7.2 JVM Phase and Timing
- 7.3 Controlling Garbage Collection
- 7.4 Object Size (Correct API)
- 7.5 Managing Native Resources
- 7.6 Thread-Local Storage
- 7.7 Complete Example: JVM Inspector Agent
- 7.8 Best Practices
- 7.9 Troubleshooting
- 7.10 What’s Next?
Chapter 8: Exception Handling and Debugging
- 8.1 Exception Events
- 8.2 The Exception Callback
- 8.3 The Exception Catch Callback
- 8.4 Capturing Exception Stack Traces
- 8.5 Complete Example: Exception Monitor Agent
- 8.6 Performance Considerations
- 8.7 Best Practices
- 8.8 Troubleshooting
- 8.9 What’s Next?
Chapter 9: Advanced JVMTI Techniques
- 9.1 Raw Monitors
- 9.2 Thread-Local Storage (TLS)
- 9.3 Agent Reentrancy
- 9.4 Native Method Binding
- 9.5 Multiple JVMTI Environments
- 9.6 Complete Example: Thread-Safe Method Counter
- 9.7 Best Practices
- 9.8 What’s Next?
Chapter 10: Building a Minimal Profiler
- 10.1 Sampling vs. Instrumentation
- 10.2 Core Architecture
- 10.3 Complete Example: Sampling Profiler Agent
- 10.4 Cross-Platform Timer Strategies
- 10.5 Production Profiler Architecture
- 10.6 Best Practices
- 10.7 Troubleshooting
- 10.8 What’s Next?
Chapter 11: Deploying and Testing JVMTI Agents
- 11.1 Agent Packaging
- 11.2 CMake Build Configuration
- 11.3 Debug vs. Release Builds
- 11.4 The Attach API
- 11.5 Measuring Agent Overhead
- 11.6 Best Practices
- 11.7 Troubleshooting
- 11.8 What’s Next?
Chapter 12: Security and Stability
- 12.1 Crash Handling
- 12.2 Thread Safety Rules
- 12.3 Container Deployment
- 12.4 JVM Vendor Compatibility
- 12.5 Least-Privilege Design
- 12.6 Best Practices
- 12.7 Troubleshooting
- 12.8 What’s Next?
Chapter 13: Case Study — Building an Allocation Tracker
- 13.1 Project Structure
- 13.2 Design Decisions
- 13.3 Complete Agent: alloc_tracker.c
- 13.4 Companion Test Application
- 13.5 Build and Run
- 13.6 Extending the Agent
- 13.7 Techniques Used (Chapter Cross-Reference)
- 13.8 Conclusion
Appendix A: Full JVMTI Capabilities Reference
- Querying Capabilities
- Debugging Capabilities
- Thread and Monitor Capabilities
- Class Transformation Capabilities
- Memory and Heap Capabilities
- Exception and Event Capabilities
- Miscellaneous Capabilities
- Quick Reference: Capabilities Used Per Chapter
Appendix B: JVMTI Error Codes Reference
- Universal Errors
- Capability Errors
- Argument Errors
- Thread State Errors
- Class and Method Errors
- Error Handling Pattern — Full Example
Appendix C: Open-Source Tools Using JVMTI
- Profiling and Monitoring Tools
- Diagnostic and Tracing Tools
- Bytecode Instrumentation Frameworks
- Commercial Tools (JVMTI-based)
- How to Learn from These Tools
Appendix D: Debugging Native Crashes in JVMTI Agents
- 1. Understanding the HotSpot Crash Log (
hs_err_pid*.log) - 2. Building with Debug Symbols
- 3. AddressSanitizer (ASan)
- 4. Valgrind (Linux/macOS)
- 5. Using GDB (Linux/macOS)
- 6. Using LLDB (macOS)
- 7. Windows Debugging
- 8. Common Crash Patterns in JVMTI Agents
- Debugging Checklist
Appendix E: JVM Compatibility Matrix
- Vendor Compatibility
- Capability Availability by Java Version
- Key Behavioral Differences
- Defensive Runtime Check
- Testing Across JVMs
Appendix F: JNI Cheat Sheet
- JNI Type Descriptors
- JNI Types and Handles
- Reference Types
- Common Operations
- Exception Handling in JNI
- Thread Attachment
- Common Pitfalls
- Additional Resources