- Introduction to profiling
- When is profiling helpful?
- Supported profiling types
- Introduction to CPU and allocation profiling
- How IntelliJ IDEA profiler works
- CPU profiling
- Memory allocation profiling
- Profiling workflow
- The Java Profiler for Every Developer
- CPU and memory live charts
- Extensive analysis
- Results import
- CPU and Allocation Profiling
- Flame graph
- Call tree
- Method list
- Timeline
- Events
- Get IntelliJ IDEA Ultimate
- Trisha Gee
- Learn more
Introduction to profiling
Profiling is a type of runtime analysis that operates on large amounts of runtime data and gives you a birds-eye view of what is happening inside a process. The collected data relates to various aspects of program operation, such as CPU usage, memory allocation, and interaction between the threads.
Profiling can be instantaneous, like capturing a memory snapshot, or long-running. For example the CPU profiler can collect data during arbitrarily large periods of time, like hours or even days of program operation.
If you are new to profiling and want to start right away, check out the available tutorials.
When is profiling helpful?
- Identify bugs, bottlenecks and diagnose poor performance
- Identify hot spots and opportunities for optimization (not necessarily related to a performance problem)
- Assess or compare the performance of different solutions
- Get a better understanding of how a program operates under the hood
Supported profiling types
IntelliJ IDEA profiler is not a single tool but rather a suite of related tools. They all have their own area of application:
- CPU and memory live charts – allow you to monitor a process in real time. This type of diagnostics gives you the resource consumption metrics over time and may be useful as a monitoring tool or, in the case of a performance problem, a starting point for further investigation. For a hands-on example, see this tutorial.
- CPU and allocation profiling – allow you to see how CPU and memory resources were utilized during a particular period of time. This may be useful for detecting hot code, opportunities for optimization, or just discovering how a program operates at runtime. For a hands-on example, see this tutorial.
- Memory snapshots – allow you to analyze how memory is used at a particular instant. This data is useful for investigating memory-related issues.
- Thread dumps — allow you to see the program state at a particular instant. The produced data captures the state of all threads. This may be useful, for example, to examine an unresponsive application.
Introduction to CPU and allocation profiling
This topic describes the basic concepts of CPU and allocation profiling. These concepts will help you understand how IntelliJ IDEA profiler works.
If you want to get your hands dirty without diving into much theory, take a look at the IntelliJ Profiler tutorial. It will get you started using a simple example and give you the idea how to use the profiler in your projects.
How IntelliJ IDEA profiler works
For CPU and allocation profiling, IntelliJ IDEA provides integration with the following profilers:
- Java Flight Recorder – a standard profiling tool shipped as part of the JDK.
- Async Profiler – a very accurate profiler that can also collect native call and memory allocation data.
By default, IntelliJ IDEA runs both profilers in parallel to provide most accurate results. While it is possible to use the supported profilers separately, the combined configuration that you get out of the box is a better choice for most scenarios. This approach leverages the advantages of both profilers and abstracts you from any setup whatsoever unless you have very specific requirements.
IntelliJ IDEA profiler collects both CPU and allocation profiling data. Here’s the brief explanation of what this means.
CPU profiling
CPU profiling works by periodically collecting the stack traces of all running threads. To achieve this, IntelliJ IDEA profiler uses both JVM and OS APIs, which allows you to get insight into the native part and ensures accurate JVM profiling even for corner-cases where profilers that only query JVM usually fail.
Profilers in IntelliJ IDEA use sampling. This means that instead of capturing all method entries and exits, which instrumentation-based profilers do, IntelliJ IDEA profiler will only get the stack traces at a regular interval.
This sacrifices a small portion of data, which does not affect the overall picture, but brings in a couple of significant benefits, such as minimized footprint on the profiled application. This gives you an unbiased view of things and even allows you to profile applications in production with little impact on their performance.
Memory allocation profiling
IntelliJ IDEA profiler reacts to memory allocation events. When such an event happens, IntelliJ IDEA profiler records the call stack for the thread from which the request was made and the type of the allocated object.
This information helps you understand which code paths account for the allocation of particular types, and how massive these allocations are.
As with CPU profiling, the profiler minimizes the footprint by only recording the data that is sufficient to form a meaningful picture.
Profiling workflow
Typically, the profiling procedure consists of the following steps:
- Collect the data. You may attach the profiler at the application start or do it at a later time. After you stop profiling, IntelliJ IDEA will generate the snapshot.
- Open and analyze the profile. At this step, the built-in tools help you organize the raw data in a meaningful form and slice it as required. The approaches to analysis may differ depending on your goal.
Either of the steps are optional. For example, in some cases you only need to collect the data and attach it to a bug report or send it over to someone. On the other hand, you can read someone else’s snapshot without running the application yourself.
The Java Profiler for Every Developer
To start profiling in IntelliJ IDEA Ultimate, click on three dots in the upper-right corner of the IDE or on a «Play» gutter icon next to a code line and select «Profile with IntelliJ Profiler».
CPU and memory live charts
IntelliJ IDEA Ultimate provides a way to monitor live performance statistics for a running process. As opposed to viewing static figures, live data can help you to visualize resource consumption, identify resource-related bottlenecks, and understand how certain events affect the program performance.
Extensive analysis
Profiler tool window features different ways to display the collected data. You can choose which one works for you – flame graph, call tree, method list, timeline, or events.
Results import
The IDE automatically saves profiling results in .jfr for CPU or memory sampling and .hprof for memory snapshots. You can open them when needed or share the results with your teammates.
CPU and Allocation Profiling
Read, analyze, and navigate profiler snapshots in the IDE.
Flame graph
This view helps you visualize the call stack for a selected thread and see how it changes over time. The wider a stack frame is, the longer the method takes to execute. The colored blocks display native, library, and user code.
Call tree
This view shows the percentage of the CPU time used by the methods, the method execution path in your application, and the total sample count. Call tree is useful for a quick overview of application activity and detection of critical execution paths.
Method list
This view shows a list of the methods executed while you were profiling your data. All of them are sorted by cumulative sample time. Each selected method has several views that show you either the method’s callers or callees.
Timeline
This is a visual representation of threads activity over time. It is helpful for detecting unusual GC activity, multithreading issues such as livelocks, and so on.
Events
This view displays the data related to JVM events like Class loading, Garbage collection, OS events, and many more.
Get IntelliJ IDEA Ultimate
The leading Java and Kotlin IDE with built-in profiling tools
Why choose IntelliJ IDEA Ultimate?
- Profile and optimize application right from the IDE
- Detect and analyze app performance bottlenecks
- Boost Java and Kotlin application productivity
“In order to get a feel for potential bottlenecks, for testing a hypothesis of “this method seems to be using a lot of memory or taking a long time, or maybe there’s a lot of these types of objects on the heap,» you can use IntelliJ IDEA’s Profiler with lower barrier to entry to test some of these hypotheses, and then start creating some more specific performance tests or profiling on a more production-like environment.”