The interaction between Java threads affects the performance of your application. There are two ways to tune the interaction of threads:
-
By modifying the structure of your program code; for example, minimizing the amount of contention between threads
-
By using options in the Oracle JRockit JVM that affect how contention is handled when your application is running
This chapter describes the following topics:
For more information about how the JRockit JVM handles threads and locks, see the "Understanding Threads and Locks" section in Oracle JRockit Introduction to the JDK.
5.1 Lock Profiling
You can configure the JRockit Flight Recorder to collect and analyze information about the locks and the contention that occurred while the Flight Recorder was recording. To do this, add the following option when you start your application:
-XX:+UseLockProfiling
When lock profiling is enabled, you can view information about Java locks on the Lock Profiling tab in the JRockit Mission Control Client.
Note:
Lock profiling creates significant (approximately 20 percent) overhead processing when your Java application runs.Two diagnostic commands are tied to the lock profile counters. To work, both require lock profiling to be enabled with the -XX:+UseLockProfiling
option. These are used with the jrcmd
utility:
-
The
lockprofile_print
command prints the current values of the lock profile counters. -
The
lockprofile_reset
command resets the current values of the lock profile counters.
For more information about diagnostic commands, see the Oracle JRockit Diagnostics and Troubleshooting Guide.
5.2 Disabling Spinning Against Fat Locks
Spinning against a fat lock is generally beneficial. However, in some instances such as when you have locks that create long waiting periods and high contention it can be expensive in terms of performance. You can turn off spinning against a fat lock and eliminate a potential performance degradation with the following option:
-XX:-UseFatSpin
The option disables the fat lock spin code in Java, enabling threads that are trying to acquire a fat lock to go to a sleep state directly.
5.3 Adaptive Spinning Against Fat Locks
You can let the JVM decide whether threads should spin against a fat lock or not (and directly go into sleeping state when failing to take it).
To enable adaptive lock spinning, use the -XX:+UseAdaptiveFatSpin
option.
By default, adaptive spinning against fat locks is disabled. Note that whether threads that fail to take a particular fat lock spin or go to sleep can change at run time.
5.4 Lock Deflation
If the amount of contention on a fat lock is small, the lock converts to a thin lock. This process is called lock deflation. Thin locks have higher performance for uncontended locks. Therefore, lock deflation is enabled by default.
If you do not want fat locks to deflate, run the application with the following option:
-XX:-UseFatLockDeflation
With lock deflation disabled, a fat lock remains as a fat lock even after there are no threads waiting to take the lock.
You can also tune for when lock deflation is triggered. Specify, with the following option, the number of uncontended fat lock unlocks that occur before deflation:
-XX:FatLockDeflationThreshold=NumberOfUnlocks
5.5 Lazy Unlocking
Lazy unlocking is intended for applications with many nonshared locks. Note that it can introduce performance penalties with applications that have many short-lived but shared locks.
When lazy unlocking is enabled, locks are not released when a critical section is exited. Instead, once a lock is acquired, the next thread that tries to acquire such a lock must ensure that the lock is or can be released. It does this by determining if the initial thread is using the lock. A shared lock converts to a normal lock and does not stay in lazy mode.
Lazy unlocking is enabled by default in the JRockit JVM for all garbage collection strategies except the deterministic garbage collector.