Till Schäfer Till Schäfer -4 years ago 188
Java Question

Java: counting/profiling synchronization calls

I am searching for a way to list all synchronization calls of a running parallel java application, in order to detect scalability problems (in terms of threads/cores). To my understanding, each time a synchronized block is entered, the machine needs to synchronize caches. This affects all CPUs running (in several ways, like memory bandwidth), even if the running tasks are not blocked by entering a synchronized region.

The setting:

I have a large application that is parallelized on a higher level, i.e. it has complex tasks that are executed in parallel. The parallelization works in the term, that all cores are under load and i have no blocked threads. Still the performance is not scaling with the cores, which may have several reasons. The particular possible reason I am interested in, is if there are a lot of synchronization calls (e.g. entering a synchronized block, using a lock, etc).

The Task

I would like to find out which places in my code (that are actually executed) have such a synchronization call and how often each synchronization is actually performed. There are many referenced libraries, therefore it is not possible to just use a regular code search on the synchronized keyword or something like that, becuase this will search a lot of never executed code and bring up a lot of false positives. The perfect solution would be to have a profiler, that lists all executed synchronization places and the number of calls. However, the profilers i tried out only allow method calls to be counted. Therefore, the problem here is to find all methods, that are actually relevant.

Alternatively, it would also help if i can just find the synchronization places referenced by some entry point (main method). I.e. by recursively going through the code and check all referenced methods, classes, etc for such synchronization. In this case it would be possible to find out the frequency later by using a regular profiler.

The Question

Are there tools or workflows, that are able to archive the task above for a larger project.

THX in advance for your answers.

Answer Source

Entering and leaving synchronized block is rather cheap operation unless there is a contention on this block. In uncontended case synchronized is just an atomic CAS or almost a no-op if UseBiasedLocking optimization succeeds. Though it looks possible to do a synchronization profiler using Instrumentation API, this won't make much sense.

The problem for multithreaded application is a contended synchronization. JVM has some internal counters to monitor lock contention (see this question). Or you can even write a simple ad-hoc tool to track all contended locks using JVMTI events.

However, not only locks can cause contention. Even non-blocking algorithms can suffer from competition for a shared resource. Here is a good example of such scalability problem. So, I would agree with @PeterLawrey that it's better to start with CPU profiler as it is usually more handy in finding performance problems.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download