JProfiler Best Practices: Powerful Performance Diagnostic Tool


Brief Introduction to Java Performance Diagnostic Tools

Simple Command Line Tools

  • jinfo — allows you to view and tune various parameters of the target JVM in real-time.
  • jstack — allows you to obtain thread stack information of the target Java process, detect deadlocks, and to locate infinite loops.
  • jmap — allows you to obtain memory-related information of the target Java process, including the usage of different Java heaps, statistical information of objects in Java heaps, and loaded classes.
  • jstat — is a light-weight versatile monitoring tool. It allows you to obtain various information about loaded classes, Just-In-Time (JIT) compilation, garbage collection, and memory usage of the target Java process.
  • jcmd — is more comprehensive than jstat. It allows you to obtain various information about the performance statistics, Java Flight Recorder (JFR), memory usage, garbage collection, thread stacking, and JVM runtime of the target Java process.

Comprehensive Graphical Diagnostic Tools

  1. They cannot obtain the method-level analytical data, such as the call relationship between different methods, and the frequency and duration that a method is called. They are very important for identifying the performance bottlenecks of your application.
  2. You must log on to the host machine of the target Java application to use them, which is not very convenient.
  3. The analytical data is generated at a terminal, and the results are not intuitively displayed.



  1. Method calls — The analysis of method calls helps you to understand what your application is doing and find ways to improve its performance.
  2. Allocations — Through analyzing objects on the heap, reference chains, and garbage collection, this functionality enables you to fix memory leaks and optimize memory usage.
  3. Thread and lock — JProfiler provides multiple analysis views on threads and locks to help you discover multithreading problems.
  4. High-level subsystems — Many performance problems occur on a higher semantic level. For example, with Java Database Connectivity (JDBC) calls, you probably want to find out which SQL statement is the slowest. JProfiler supports integrated analysis of these subsystems.

Distributed Application Performance Diagnosis

Introduction to JProfiler

Core Components

JProfiler Agent

JProfiler UI

Command Line Tools

  • jpcontroller — is used to control how the agent collects data. It sends instructions to the agent through the JProfiler MBean registered by the agent.
  • jpenable — is used to load the agent to a running JVM.
  • jpdump — is used to capture the heap snapshots of a running JVM.
  • jpexport & jpcompare — is used to extract data and create HTML reports from previously saved snapshots.


  1. Install JProfiler UI locally.
  2. Install JProfiler agent on the remote host machine, and load it to the target JVM.
  3. Connect JProfiler UI to the agent.

Best Practices

JProfiler Settings

Data Collection Mode

  • Sampling — suitable for scenarios that do not require high data collection accuracy. The advantage of this method that it has low impact on system performance. The drawback is that it does not support some features such as method-level statistics.
  • Instrumentation — the complete data collection mode that supports high accuracy. The drawback is that it must analyze many classes and it has a relatively heavy impact on the application performance. To reduce the impact, you may want to use it with a filter.

Startup Modes of the Application

  • Wait for connection from the JProfiler GUI — The application is started only when JProfiler GUI establishes connection with the profiling agent, and the profiling settings are completed. With this option you can profile the startup phase of your application. The command that you can use to enable this option: -agentpath:<path to native library>=port=8849.
  • Start immediately, connect later with the JProfiler GUI — JProfiler GUI establishes connection with the profiling agent when it is necessary, and transmits the profiling settings. This option is flexible, but it cannot profile the startup phase of your application. The command that you can use to enable this option: -agentpath:<path to native library>=port=8849,nowait.
  • Profile offline, JProfiler cannot connect — You have to configure triggers that record data and save snapshots that can be opened with the JProfiler GUI later on. The command that you can use to enable this option: -agentpath:<path to native library>=offline,id=xxx,config=/config.xml.

Use JProfiler to Diagnose the Application Performance


  1. A large number of objects are generated during the application running process. These objects have a very short lifecycle, and most of them can be promptly recycled by the garbage collector. They won’t cause memory usage to continually grow.
  2. As expected, the number of loaded classes increases rapidly during the startup period, and stabilizes afterward.
  3. When the application is running, many threads are blocked. Extra attention must be paid to this issue.
  4. At the startup phase of the application, the CPU usage is high. We need to find out why.

CPU Views

Call Tree

Hot Spots

Call Graph

Live Memory

All Objects

Allocation Call Tree

Allocation Hot Spots

Thread History

  • The thread Pool-1-thread-<M> periodically calls the Producer.send () method to asynchronously send data. They continued to run while the application was starting, but was mostly blocked afterwards. The cause of this phenomenon is that Producer sends data slower than the data generation speed, and the cache size of each Producer instance is limited. After the startup of the application, Producer had enough memory to cache the data that is waiting to be sent, so pool-1-thread-<M> remained running for a while. This explains why the application had high CPU usage at startup. As time passed by, the cache memory is fully occupied. pool-1-thread-<M> must wait until Producer releases sufficient space. That is why a large number of threads are blocked.
  • aliyun-log-producer-0-mover detects and sends expired batches to IOThreadPool. The data accumulation speed is fast, a producer batch is sent to IOThreadPool by pool-1-thread-<M> immediately after the cached data size reached the upper limit. Therefore, the mover thread remained idle most of the time.
  • aliyun-log-producer-0-io-thread-<N> sends data from IOThreadPool to your designated logstore, and it takes most of the time on the network I/O status.
  • aliyun-log-producer-0-success-batch-handlerhandles batches that were successfully sent to the logstore. The callback is simple and it takes a very short time to execute. Therefore, the SuccessBatchHandler remained idle most of the time.
  • aliyun-log-producer-0-failure-batch-handler handles batches that failed to be sent to the logstore. In our case, no data has failed to be sent. It remained idle all the time.

Overhead Hot Spots Detected



Original Source




Follow me to keep abreast with the latest technology news, industry insights, and developer trends. Alibaba Cloud website:

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Recent Developments in monitoring AWS Lambda in Python

Mobile devices and mobile operating systems

Apache Hop, installation on Windows 10/11

Docker Swarm Mode and Distributed Traefik proxy with HTTPS

Alibaba Cloud Unveils New Spring Boot Scaffold

Default view vs Selected view in PowerBI

Swift: easy way to add tap gesture on a View

How to run odoo tests with Pycharm

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Alibaba Cloud

Alibaba Cloud

Follow me to keep abreast with the latest technology news, industry insights, and developer trends. Alibaba Cloud website:

More from Medium

Apache Kafka

When Elastic Search masquerades as a database…

Introduction to HBase

How to build an HTTP client from scratch

Redpanda mascot with settings symbol