Master Java Profiling: Tools, Techniques, and Real-World Tips

Transcript

Imagine that your code is a sleek sports car, but for some reason you're driving it with the handbrake on.

Today I will tell you how to release the handbrake and unleash the full potential of your application. Hi, my name is Catherine Edelveis, and in this video I will guide you through the intricacies of Java profiling. If you master profiling techniques, you will be able to find and fix the performance bottlenecks in your application quickly. We will look into key concepts and areas of Java profiling, try out some popular tools, and unveil the useful tips for Java profiling. Java profiling is the process of analyzing the application behavior running on Java Virtual Machine, and the analysis happens at runtime. Profiling usually deals with low-level processes and helps to get data on CPU usage, memory allocation, garbage collection, thread behavior, and other JVM operations. It also helps to identify memory leaks and thread locking issues.

Some modern profilers can also get data on the performance of database queries and web requests. Profiling is a must-have procedure for finding out the root causes of deteriorated performance of your Java programs. It may also be required if you are adding a critical feature to your application. There are two types of profilers: instrumenting and sampling ones. Instrumenting profilers insert method invocation logging into the application code. This approach is easier to implement, and developers don't even need to use specific tools for some basic measurements. But this approach offers very limited information and is associated with a serious overhead. Sampling profilers periodically receive from the JVM the stack trace of each thread running at this point of time, and then the profiler aggregates the samples and provides a general picture of application behavior. This approach has smaller overhead and can yield data on various JVM operations, but the results sometimes can be inaccurate depending on how often, for how long, and at which points the profiler took the samples.

Now let's look at some popular profiling tools. Jaba Flight Recorder or JFR is a profiling and diagnostic tool built into the OpenJDK. It collects data about various JVM events, and it can collect data on hundreds of event types, plus you can create your custom events. JFR recordings are binary log files that can be analyzed in JDK Mission Control. JDK Mission Control is a set of profiling and monitoring tools for Java applications. It has a graphic user interface, and you can use it as a standalone tool to monitor the application behavior in real-time or you can analyze JFR files in JDK Mission Control. You can start JFR upon application startup or use the jcmd tool to start and stop recordings at an arbitrary point of time. You can also perform continuous recording. You can analyze JFR files in JDK Mission Control. There are lots of reports for analyzing JVM events, and you can also customize them. So the advantages of JFR is that it is very easy to use because it is deeply integrated into the OpenJDK, and it can profile a very large number of events, and it has a very low overhead, so you can even use it in production. But it is not suitable for distributed systems. And it's a use only .jfr files.

VisualVM is an open-source Java profiler that uses the JMX API to collect the data. Basic VisualVM functionality include monitoring CPU and memory usage, garbage collection, thread behavior, and heap. You can use additional plugins to profile some other areas. To use VisualVM, simply choose a running local or remote JVM process and analyze the app in real time. You can also save the snapshots to analyze them later. To sum up, VisualVM is easy to use, it is free and open source, but it has limited functionality. Async Profiler is a free and open-source profiler that collects data on CPU cycles, hardware and software performance counters, allocations in Java Heap and contented lock attempts. It can produce JFR files and flame graphs. You can attach it as a ‘-javaagent’ at application startup, or connect to the running JVM process at an arbitrary point of time. You can analyze JFR files in JDK Mission Control and flame graphs in the browser. IAsync Profiler has a very low overhead, and it is free and open source, and it can also be embedded into other solutions. But there is no graphic user interface and it is not available for Windows. New Relic is not only a profiler, but an Application Performance Monitoring tool that offers a wide variety of features.

The features include: anomalies alert, infrastructure monitoring, security testing, and many more. The available services depend on the subscription plan, but there is a Freemium license for small teams and limited data ingest. Once you have completed the installation process, you can attach the New Relic agent to the JVM process just like any other profiler. The solution provides multiple dashboards to analyze the data in real-time or post factum. So, New Relic offers advanced analytics and it is suitable for distributed systems, but it takes time to set up, and a full set of features requires a subscription.

Digma integrates into Intellij IDEA as a plugin. It uses OpenTtelemetry under the hood to collect the data about the running code, and then provides reports on performance bottlenecks, code smells, and other performance issues related to your code. It can collect data on CPU and heap usage too, but its main focus is on the code. Using Digma is super easy. Simply install the plugin, follow the instructions to set up the analytics engine, and you're ready to go. So each time you run your code with Digma enabled, it runs silently in the background and collects data about your code. And then you can analyze the reports right in the Intellij IDEA. So Digma is really simple to use and it offers unique insights into the code. But it has limited analytics of low-level JVM processes, and it is available only as an Intellij IDEA plugin. JProfiler is a Java profiler with the graphic user interface. It offers a wide range of features, including CPU and memory profiling, database queries profiling, and web request profiling. It also uses an advanced tool called heap walker to identify the memory leaks. You can use it separately or integrate with your IDE as a plugin. It also offers a facilitated access to Kubernetes and Docker environments. It is possible to monitor the app in real time, or save the snapshots and analyze them later. So JProfiler can profile various areas and it has a convenient user interface, but it is a commercial product. YourKit is a Java profiler that can retrieve the data about multiple areas: CPU and memory, threads, database queries, web requests. It comes with a user interface, but it can also be used as a command line tool. The profiling results can be exported into various formats, including the flame graphs. Another useful feature called ‘What-If’ can analyze the possible improvements of a supposed performance optimizations without reprofiling the code. So YourKit offers deep analytics and some unique features, but it is a commercial product. All right, let us now look at the best practices of Java profiling. It is very tempting to grab a feature-packed profiler, collect tons of data about your code, and dig into optimizations. Well, don't do that. Premature optimization is the root of all evil. If SLAs are not broken and cloud costs don't spill over the edge, don't waste your time on fine-tuning small imperfections.

Check against the established key performance indicators and solve the problems that prevent your team from reaching them. Speaking of KPIs, choose the areas that are most important to optimize. Also, select the metrics that are most important for each area. Use this data as a reference when studying the profiling data. The profiling data is not always accurate. It depends on numerous factors: when the samples were taken, for how long, the profiler overhead, and the frequency of sampling, to name a few. So you can choose a low-overhead profiler and adjust the period of sampling. Or you can also use different profilers and then compare the results. Profiling an application on the local machine will not always give relevant results. Profile the application in Docker, Kubernetes, or in any other environment where your application runs. The application may behave differently in different environments. Also, use load testing and stress testing to see what happens in critical situations. Profilers can give information about low-level processes in the JVM, such as CPU and memory usage, but it is only part of the deal. You should use additional tools to get a data on response times, transaction rates, Inter-service communication, uptime, and so on.

Consider using an application performance monitoring tools such as New Relic to get the full picture of your application behavior. Today we looked at different tools and techniques for Java profiling. If you choose the right profiling tool that best suits your need and follow the best practices of profiling, you will be able to get valuable data about the behavior of your application and solve the performance issues quickly. If this video was useful to you, like it and subscribe to our channel. See you next time!

Summary

If your Java apps in the cloud struggle with high resource consumption, frequent container restarts, or slow response times, these five tips can help enhance their performance. First, set CPU and RAM limits properly based on load testing and account for Kubernetes overhead. Additionally, configure Kubernetes probes accurately, use a small base image to optimize container size, choose a suitable garbage collector, and reduce application startup and warmup time to ensure faster performance.

About Catherine

Java developer passionate about Spring Boot. Writer. Developer Advocate at BellSoft

Social Media

Videos
card image
Jan 20, 2026
JDBC vs ORM vs jOOQ: Choose the Right Java Database Tool

Still unsure what is the difference between JPA, Hibernate, JDBC, or jOOQ and when to use which? This video clarifies the entire Java database access stack with real, production-oriented examples. We start at the foundation, which is JDBC, a low-level API every other tool eventually relies on for database communication. Then, we go through the ORM concept, JPA as a specification of ORM, Hibernate as the implementation and extension of JPA, and Blaze Persistence as a powerful upgrade to JPA Criteria API. From there, we take a different path with jOOQ: a database-first, SQL-centric approach that provides type-safe queries and catches many SQL errors at compile time instead of runtime. You’ll see when raw JDBC makes sense for small, focused services, when Hibernate fits CRUD-heavy domains, and when jOOQ excels at complex reporting and analytics. We discuss real performance pitfalls such as N+1 queries and lazy loading, and show practical combination strategies like “JPA for CRUD, jOOQ for reports.” The goal is to equip you with clarity so that you can make informed architectural decisions based on domain complexity, query patterns, and long-term maintainability.

Videos
card image
Jan 13, 2026
Hibernate: Ditch or Double Down? When ORM Isn't Enough

Every Java team debates Hibernate at some point: productivity champion or performance liability? Both are right. This video shows you when to rely on Hibernate's ORM magic and when to drop down to SQL. We walk through production scenarios: domain models with many-to-many relations where Hibernate excels, analytical reports with window functions where JDBC dominates, and hybrid architectures that use both in the same Spring Boot codebase. You'll see real code examples: the N+1 query trap that kills performance, complex window functions and anti-joins that Hibernate can't handle, equals/hashCode pitfalls with lazy loading, and practical two-level caching strategies. We also explore how Hibernate works under the hood—translating HQL to database-specific SQL dialects, managing sessions and transactions through JDBC, implementing JPA specifications. The strategic insight: modern applications need both ORM convenience for transactional business logic and SQL precision for data-intensive analytics. Use Hibernate for CRUD and relationship management. Use SQL where ORM abstractions leak or performance demands direct control.

Further watching

Videos
card image
Feb 6, 2026
Backend Developer Roadmap 2026: What You Need to Know

Backend complexity keeps growing, and frameworks can't keep up. In 2026, knowing React or Django isn't enough. You need fundamentals that hold up when systems break, traffic spikes, or your architecture gets rewritten for the third time.I've been building production systems for 15 years. This roadmap covers three areas that separate people who know frameworks from people who can actually architect backend systems: data, architecture, and infrastructure. This is about how to think, not what tools to install.

Videos
card image
Jan 29, 2026
JDBC Connection Pools in Microservices. Why They Break Down (and What to Do Instead)

In this livestream, Catherine is joined by Rogerio Robetti, the founder of Open J Proxy, to discuss why traditional JDBC connection pools break down when teams migrate to microservices, and what is a more efficient and reliable approach to organizing database access with microservice architecture.

Videos
card image
Jan 27, 2026
Sizing JDBC Connection Pools for Real Production Load

Many production outages start with connection pool exhaustion. Your app waits seconds for connections while queries take milliseconds; yet, most teams run default settings that collapse under load. This video shows how to configure connection pools that survive real production traffic: sizing based on database limits and thread counts, setting timeouts that prevent cascading failures, and implementing an open source database proxy Open J Proxy for centralized connection management with virtual connection handles, client-side load balancing, and slow query segregation. For senior Java developers, DevOps engineers, and architects who need database performance that holds under pressure.