OpenJ9 Locking/Synchronization

OpenJ9 Java Virtual Machine (JVM) implements the synchronization features needed for the Java language. Also, OpenJ9 is a multi-threaded application with virtual machine (VM), garbage collector (GC), just-in-time (JIT) and other native threads which require synchronization. This is the main blog a.k.a blog 1 which summarizes the various data structures and features used to support synchronization internally within OpenJ9 and for the Java language. Synchronization is analogous to locking or usage of locks to manage shared resources between threads. Each OpenJ9 synchronization data structure and feature has a sub-blog where it is discussed in greater detail. For the readers with no background on locks and synchronization, a basic introduction to these topics is here.

All the blogs in the OpenJ9 locking/synchronization series are listed here.

Data-structures

OpenJ9 uses four types of native locks or synchronization data structures:

  • GC-spinlocks (J9GCSpinlock; GC – Garbage Collector)
  • System-monitors (omrthread_monitor_t)
  • Raw-monitors (JVM_RawMonitor*)
  • Object-monitors (J9ObjectMonitor)

A system-monitor (blog 2) is used for internal locking between the VM, GC, JIT, and native threads, and to support object-monitors. It is of type omrthread_monitor_t, and includes its own structures and logic. If the logic of a system-monitor cannot avoid suspending a thread, then it defers to the operating system (OS) specific synchronization primitives.

A GC-spinlock (blog 2) is similar to an system-monitor, but it supports a more limited set of functionality and is optimized to be as lightweight as possible. It is only used by the garbage collector (GC).

A raw-monitor (blog 2) is provided to the Java class library code via the JVM_RawMonitor* API.  It is essentially an opaque pointer to a system-monitor.  JVMTI raw monitors are similar.

An object-monitor (blog 3) supports synchronization at the Java level. Java specifies an object-monitor for each object. A monitor is used to synchronize an object. For example, invoking a synchronized block or synchronized method of an object X uses the object-monitor of object X for synchronization. The object-monitors are of the type J9ObjectMonitor, each with their own structures and logic. If an object-monitor’s logic cannot avoid suspending a thread, then it relies on a system-monitor to do the suspension.

Architecture Overview

The figure below provides a basic architecture overview with a focus on Java, OpenJ9, OMR and locking.

  • The Java component includes the synchronized methods, synchronized blocks, java.lang.Object (wait/notify), java.util.concurrent package and other support for concurrent programming.
  • The OpenJ9 component supports the object-monitors and exposes the JVM and JVMTI raw-monitors.
  • The OMR thread library supports the system-monitors and the GC-spinlocks.
  • The OMR port library provides an API for basic cross-platform operations such as memory allocation, file operations, retrieving system information, signal handling, etc.
Architecture Overview

Features

Locking/Synchronization features available in OpenJ9:

  • Three-tier Spinning
  • Adaptive Spinning
  • Lock Nursery
  • Lock Reservation
  • Class-specific Spin Parameters

The three-tier spinning (blog 4) strategy contains three tiers, such that each tier has an incrementally larger wait-interval between attempts to acquire a lock while spinning. Each tier is dependent on two kinds of locking structures/calls: lightweight and heavyweight. Initially, the lightweight structures/calls are used for a specific number of spins. When the spin is exhausted, the heavyweight structures/calls are used, which put the thread into a suspended state that does not utilize the CPU.

The adaptive spinning (blog 5) strategy identifies cases where lock spinning regresses performance and disables spinning for those cases.

The lock nursery (blog 6) reduces memory usage by efficiently storing the thin/flat locks (lock-words) related to the object-monitors.

The lock reservation (blog 7) strategy is an optimization for thin/flat locks (lock-words). It exploits the thread locality of object-monitors and reduces the need for compare-and-swap operations that stall the CPU.

The class-specific spin parameters (blog 8) allow the spin parameters to be varied for all the instances of a class.

Future Blogs

  • omrthread_rwmutex_t (blog 9): Readers-writer (RW) lock developed using a system-monitor.
  • VM Access (blog 10): Synchronization feature for manipulating Java objects within OpenJ9. There are two modes: shared VM access for reading objects and exclusive VM access for writing/editing objects.
  • Deadlock Detection, Lock Contention and Locking Performance (blog 11).

5 comments

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s