Offline profiling WSO2 Identity Server using JProfiler

Dinika Senarath
6 min readJan 16, 2021

JProfiler is one of the most popular Java Profilers used by developers to monitor the system performance, threads, memory usage etc. to identify what areas of the Java applications’s code should be improved, modified, or eliminated. JProfiler provides an intuitive GUI that allows you to analyze the profiling data of Java applications including CPU profiling, memory profiling, method call recording, thread profiling etc. The GUI provides you with buttons to start and stop recording profiling data, and shows the above mentioned profiling data to you in real time.

However, there can be situations where you want to profile a JAVA application without attaching the JProfiler GUI and analyze the recorded profiling data later. That is when JProfiler’s Offline Profiling options comes in handy. This offline profiling option allows you to start the Java application and record profiling data without having to connect to the JProfiler GUI. In this article I will guide you through the steps to collect profiling data of a WSO2 Identity Server instance running in a remote machine using the offline profiling option of JProfiler. Even though I use WSO2 Identity Server as a reference, these steps can be applied to offline profiling an Java application you want to profile.

To initiate and perform offline profiling with the JProfiler profiling agent, we need to first create an offline session in JProfiler and export the offline session configs as a file. We can configure an offline profiling session using the JProfiler GUI.

1. Open JProfiler and go to Session > New Session. This will open the Session Settings window.

2. In the left side panel, click on Profiled JVM under Application Settings. You can provide a name to your session under Session name field. Select Attach as the Session Type, and select Attach to remote JVM as the Attach type. Since the attaching agent will also be in the same remote machine in which the WSO2 IS (the Java Application) is residing, configure a direct connection to localhost’s profiling port (127.0.0.1:8849). This configuration is the default one, so you don’t need to modify the existing config. Note the session id displayed right next to Session name as we will be needing it in a later step.

In this offline profiling scenario, there are two mandatory actions we need to take. One is saving at least one snapshot with recorded profiling data while the profiling takes place so that we can analyze it later using the JProfiler GUI. If we do not save snapshots, we will not have profiling data to analyze later 😀. The second one is, if we want to see CPU or allocation data during the profiled time, we have to start recording those data at some point during the profiling (before saving the snapshot of course 🙂). Now let’s see how we can invoke these 2 actions while the profiling takes place in the remote JVM.

There are two ways to invoke the profiling actions in the Java application. The first method is using the profiling API through which you can programatically invoke the profiling actions in the Java code. However, there is a much easier way to invoke the profiling actions without touching the source code of the application which uses Triggers. There are several types of triggers that activate when different events occur in the JVM. In this example, we will use Timer triggers which allow us to periodically execute profiling actions based on the timer configuration. We will create 2 timer triggers — one to start recording profiling data (CPU, allocations etc.), and another one to save snapshots of the recorded data periodically.

3. In the left side panel, click on Trigger Settings > Triggers. Click on the green + icon to Add a new Trigger. It will open a wizard to create a trigger. From the Trigger Type drop-down, select Timer and click Next. The first trigger we will be configuring is used to start recording CPU and allocation data. That is an event which should be happening only once. Hence the trigger should be executed only once. The below config will ensure the start recording action will be triggered only once after 1 minute from JVM start time. You may change the offset to match your requirement.

4. The next step in the wizard let’s us add actions that need to be triggered based on the timer. Click on green + icon and select Start recording under Record profiling data from the actions list. Click OK. Define what are the information that should be recorded and Click Next. Proceed with default configurations until the configuration is completed. Now we have configured the start recording action to start 1 minute after JVM starts up.

5. Similarly, we need to configure saving snapshots periodically. Add a new timer trigger using + icon. This time, the action should run periodically, hence the timer configuration should be different. In my configuration, the action will be triggered every 5 minutes for 12 times starting 1 minute after JVM startup.

The configured action should be Save Snapshot.

Provide a name for the snapshot file and proceed the wizard until trigger configuration is completed.

Now we have 2 timer triggers configured for our offline profiling session.

5. Under Advanced Settings, you can configure the settings specific to CPU profiling, memory profiling etc. You can refer to JProfiler Official Documentation for more information on this.

6. After configuring all aspects of the profiling session, we can save the session by clicking OK. When you click OK, the session configuration will be written to ~.jprofiler12/jprofiler_config.xml file. If we open the file, we will see the session configuration under the relevant session ID.

7. Now we have to copy the session config file, and the JProfiler library files needed to execute the profiling agent to the remote machine where WSO2 IS (or your Java application) runs. The config file can be found in ~.jprofiler12/jprofiler_config.xml. the required library files can be found in jprofiler12/bin directory.

8. On the remote machine, open the <WSO2_IS_HOME>/bin/wso2server.sh and add the below command to the Java command.

-agentpath:<PATH_TO_JPROFILER_LIBRARY>/bin/linux-x64/libjprofilerti.so=offline,id=<SESSION_ID>,config=<PATH_TO_CONFIG_FILE>/jprofiler_config.xml

9. Start WSO2 IS with sh wso2server.sh command. You will see the below log in the terminal.

JProfiler> Protocol version 64
JProfiler> Java 8 detected.
JProfiler> Offline profiling mode.
JProfiler> 64-bit library
JProfiler> Using config file /home/ubuntu/.jprofiler12/jprofiler_config.xml (id: 107)
JProfiler> Listening on port: 8849.
JProfiler> Enabling native methods instrumentation.
JProfiler> Can retransform classes.
JProfiler> Can retransform any class.
JProfiler> Native library initialized
JProfiler> VM initialized
JProfiler> Using sampling (5 ms)
JProfiler> Time measurement: elapsed time
JProfiler> CPU profiling enabled

Based on the timer trigger you configured, the snapshot files for the recorded profiling data will be written to the <WSO2_IS_HOME> directory. You can later download them and view in the JProfiler GUI.

Reference :

https://www.ej-technologies.com/resources/jprofiler/help/doc/main/offline.html

--

--