Java diagnostics, IBM style, Part 3: Diagnosing synchronization and locking problems with the Lock Analyzer for Java

Reduce lock contention and improve performance

The IBM Lock Analyzer for Java, available from alphaWorks, provides real-time lock monitoring on a running Java application. It highlights threads suffering from lock contention that could be hurting application performance. Developers can use this information to modify their applications to reduce lock contention and thus improve performance. This article introduces the IBM Lock Analyzer for Java, explains the architecture on which it is built, and provides some thoughts about the tool's future direction.

18 July 2013 - Added new resource item for the article, "Java Technology Community," to Resources).


Toby Corbin, Software Engineer, IBM Japan

Toby CorbinToby Corbin is a software engineer currently developing RAS tooling within the IBM Java Technology Centre. He joined IBM in 2001 and spent four years developing national language support and globalization of the Java Runtime Environment, followed by two years developing the Swing and AWT libraries.

18 July 2013 (First published 16 October 2007)

Also available in Chinese

About this series

Java diagnostics, IBM style explores new tooling from IBM that can help resolve problems with Java applications and improve their performance. You can expect to come away from every article with new knowledge that you can put immediately to use.

Each of the authors contributing to the series is part of a new team that creates tools to help you resolve problems with your Java applications. The authors have a variety of backgrounds and bring different skills and areas of specialization to the team.

Please contact the authors individually with comments or questions about their articles.

Many of today's Java applications take advantage of the language's ability to support concurrent programming through the use of threads. Multiple threads can potentially share the same data objects, but if the part of your application that controls these threads is designed poorly, you may experience lock contention and correspondingly poorer performance.

In multithreaded applications, for example, if multiple threads access the same resource for reading and writing, thread synchronization problems can occur. If one thread attempts to read from a file whilst another is writing to it, the data may become corrupted. To resolve this problem, the Java language allows a thread to acquire an exclusive lock on objects, preventing any other thread accessing it. Once the thread has finished with the object, it releases it so that other threads can then gain access. However, this mechanism can cause high levels of contention if applications aren't designed with care.

Lock contention occurs when a lock is currently in use and another thread attempts to acquire it by another thread. High levels of contention can occur on locks that are frequently obtained, held for a long time, or both. A highly contended lock (one in which many threads try to gain access) can become a bottleneck in the system, as each running thread will pause its execution until the lock it requires becomes available, limiting application performance.

Guard against locking problems with the JLA

The IBM Lock Analyzer for Java (JLA), a new tool available from alphaWorks that runs on any platform running an IBM-supplied Java SDK or JRE, version 5.0 or above, performs lock analysis on a live application to highlight thread activity and provides insight into how often locks are contended. This view can help with the resolution of lock contention problems and performance issues.

The JLA runs alongside an existing Java application and gathers all of that application's lock information. Each lock is recorded along with details about it, such as how long it is held, whether it contends, and the percentage of the time it blocks threads trying to obtain it. The tool consists of a runtime library that must be loaded at startup with the application you wish to monitor and a front-end graphical user interface that displays the results and performs analysis.

JLA design details

The JLA consists of the following two packages:

  • JLAagent. This package, which is platform-dependent and made up of a platform-specific library file and a set of Java classes packaged into a JAR, provides the connection to the Java virtual machine (JVM) to gather the lock statistics on the running application.
  • JLAGui. This package, written using Swing, is platform-independent and provides the graphical user interface.

The native library in the JLAagent is written in C and uses the Java Virtual Machine Tool Interface (JVM TI). This interface provides methods to control the execution of applications running inside the JVM. It is through this interface that you can gather thread statistics by making use of functions available in the IBM-released JVM. You can have the JVM load this native library JVM at startup by making a modification to the startup command of the Java application that you wish to analyze. The native library then uses the Java classes packaged with it to create a platform MBean server, which provides the mechanism that allows the JLAGui to connect to the JLAagent.

Once the MBean server has been started, the JLAGui can request lock statistics from the running application by navigating though the server into the native library and then on into the running JVM. Because the JLAagent and JLAGui are connected by MBeans, they do not have to run on the same machine; the JLAGui can connect to the MBean server from anywhere on the network.

Running the JLA

To run the JLA, you first need to configure your application with the JLAagent. Then you can launch the JLAGui to begin monitoring lock performance. If you haven't already done so, download the JLA so that you can follow along.

Configuring an application to use the JLA

There are several versions of the JLAagent, one for each of the platforms supported by an IBM-supplied JRE; you must make sure that you use the JLAagent that corresponds to the platform on which the application you wish to monitor will run. If you use an incorrect version of the JLAagent, the application you're trying to monitor will fail to load and will crash. Each JLAagent package has a name based on the architecture of the JRE that is going to launch it.

Unpack the JLAagent package to a directory on the machine running the application you want to monitor. Add this directory to the Java classpath and the system path. A properties file called is included in the package; it contains the connection information for launching the MBean server. You can edit this properties file if you wish to modify the default values.

To load the JLAagent with the application to analyze, modify the startup command for the application. Add the -agentlib:JLAtiagent parameter so that it loads the native library, add the JLAtiagent.jar added to the classpath, and specify the location of the file.

For example, the startup command java dummy.class would need to be modified as follows:

     -agentlib:JLAtiagent -cp .;JLAagent.jar dummy.class

If an exception occurs at this point, check to make sure that the correct version of the JLAagent is being used. If everything is OK, the message JLA Client registering MBeanServer will appear on the command line.

At this point, the JLAagent has instructed the VM to start recording lock details even though the JLAGui is not running. This means that when the JLAGui is started, you will be able to view lock statistics for the lifetime of the application.

The JLAGui

You can launch the JLAGui with the following command:

java -jar JLAGui.jar

By default, the JLAGui will look for an MBean server running on port 1972 on the localhost; as such, these values need not be specified. But if you want to use different values, either the host or the port value can be modified on the command line, as shown in Table 1:

Table 1. Connection options for JLAGui
SettingDefaultDescription to match the value used by the JLAtiagent be set to an IP address or valid hostname if you wish to monitor an application running on a remote machine

When the GUI launches, it will attempt to connect to the agent through the MBean server that is running on the machine and port number you specified in the startup options. If the connection is successful, the screen in Figure 1 will appear:

Figure 1. The initial JLA screen
The initial JLA screen

If the connection is unsuccessful, an error message will appear with the details of the connection the GUI tried to make. Check over the error message to make sure the connections are correct. If necessary, you can close the GUI and restart with amended command-line options. Alternatively, you can check to make sure that the application you want to analyze is running with the native agent attached.

Click the Create Report button to create a snapshot report of the current thread statistics of the application that you're monitoring. You'll see three panels (see Figure 2), which show the Java monitors (those created by the application), the system monitors (those created by the VM), and a summary report page. Any monitor created or used by the application will have an entry in the table and graph. You will see only one entry per monitor even if multiple threads are accessing it. This data is recorded at the monitor level rather than a thread level.

Figure 2. Sample JLA report

The height of each column is based on the value of the slow lock count and is relative to all the columns in the graph. A slow count occurs when the requested monitor is already owned by another thread and the requesting thread is blocked. The color of each bar is based on the value of the %MISS column (see Table 2), with a gradient moving from red (100%) through yellow (50%) and finally on to green (0%). A red bar indicates that the thread blocks every time the monitor is requested, whereas a green bar indicates a thread that never blocks. A quick scan of the graph will show those monitors that are not performing very well.

Table 2 explains the values of the various columns in the report table:

Table 2. Report table legend
Column nameDescription
%MISSPercentage of the total gets (acquires) where the requesting thread was blocked waiting on this monitor.
GETSTotal number of successful acquires.
NONRECTotal number of nonrecursive acquires. This number includes SLOW gets.
SLOWTotal number of nonrecursive acquires that caused the requesting thread to block waiting for the monitor to be freed. This number is included in NONREC.
RECTotal number of recursive acquires. A recursive acquire is one where the requesting thread already owns the monitor.
TIER2Total number of Tier 2 (inner spin loop) iterations on platforms that support three-tier spin locking.
TIER3Total number of Tier 3 (outer thread yield loop) iterations on platforms that support three-tier spin locking.
%UTILMonitor hold time divided by interval time. Hold time accounting must be switched on.
AVER_HTMAverage amount of time the monitor was held; recursive acquires are not included because the monitor is already owned when acquired recursively.
MONITOR NAMEMonitor name or NULL (blank) if name is not known.

The JLA in action

A simple example application will help you understand how you can use the JLA to help find areas of lock contention. Imagine an application that consists of two threads, both trying to access the same object. In this case, the object is a class called JLAsink that contains two synchronized methods, one for setting a piece of data and one for retrieving it. Both threads are started at the same time and both run in a loop trying to access JLAsink simultaneously. One thread calls the setter method and the other thread calls the retrieval method.

Figure 3 shows the result of running the JLA against a poorly performing version of this sample application:

Figure 3. Initial snapshot of the JLA
Snapshot of the JLA run against badly performing application

You can see from this screenshot that the JLAsink monitor has had 9,161 gets made on it and that the requesting thread was blocked trying to obtain the lock 25 percent of the time. It's clear that this area of the application is not performing particularly well when it comes to handling threads trying to obtain this lock.

Figure 4 shows the JLA running against a much more efficient version of the sample application:

Figure 4. Snapshot of JLA run against optimized application
results after thread changes

You can see that the JLAsink monitor has had 9,370 gets made on it and not a single one has blocked. This shows that this monitor is behaving optimally when it comes to handling lock contention. The optimized code is now running faster than the non-optimized code, which you can see by comparing the interval times of each run. The second run accessed the JLAsink object more times than the first run and did it in less time.

Future plans

The development of this tool is being frozen with the current functionality in place. In the future, our team will release a new tool based on the JLA that will provide analysis of live Java applications that goes beyond lock statistics. This tool will take on the functionality of not just the JLA, but also the EVTK and Dump Analyzer tools that you learned about in the earlier articles in this series. This tool is currently in the design stage.

Next up...

In the next article in the series, you'll return to the Dump Analyzer tool introduced in Part 1 of this series. You'll get a much more in-depth look at the tool's extensibility and learn how to build your own analysis modules for it.



Get products and technologies


  • IBM Java Runtimes and SDKs: Visit this discussion forum for questions related to the IBM Developer Kits for the Java Platform.
  • Java Technology Community: Interact with industry experts as J2EE architects, developers and programmers share their knowledge and experiences on the technology.


developerWorks: Sign in

Required fields are indicated with an asterisk (*).

Need an IBM ID?
Forgot your IBM ID?

Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.


All information submitted is secure.

Dig deeper into Java technology on developerWorks

Zone=Java technology
ArticleTitle=Java diagnostics, IBM style, Part 3: Diagnosing synchronization and locking problems with the Lock Analyzer for Java