Red Hat Linux 9 and Java 2 Platform, Standard Edition 1.4.2: A Winning Combination


Articles Index

Users running Java applications on Linux will now benefit from some significant improvements in both the Java platform and the Linux OS.

Red Hat Linux 9, with its new thread library, Native POSIX Thread Library (NPTL), along with changes in the Java 2 Platform, Standard Edition 1.4.2 (J2SE 1.4.2), combine to deliver improved startup time, reliability. and scalability out of the box. The result for developers is that their applications will not only start faster, but will reliably scale to a larger number of threads than was previously possible.

"This is a very exciting time for Java Linux developers."

- Calvin Austin, lead engineer on the port of J2SE to the Linux OS, and J2SE 1.5 specification lead, Sun Microsystems

Historically, many developers who have used Java technology on Linux were initially concerned about the number of processes required to run even the simplest Java program. The source of this concern was rooted in the implementation of the system threads library on Linux. Since Linux threads are implemented as a cloned process, each Java thread appeared as a new Linux process. The advantage of this approach was that the threads implementation was simple and stable.

However, this simplicity caused problems for large threaded applications. The LinuxThreads implementation lacked the necessary support from the kernel and had to implement key functionality inappropriately at the user level. This not only resulted in performance penalties, but also affected the reliability of some applications, since signals were used to provide thread synchronization.

These scalability and signal-handling issues were well known in the Linux community. As a result, a new library, NPTL, was created to solve the problem.

"The NPTL approach keeps the 1-on-1 thread mapping (1 user or Java thread to 1 kernel thread), but leverages the kernel for thread-related operations, including signal handling, synchronization, and thread creation speed," explains Calvin Austin, who serves as both lead engineer on Sun Microsystems' port of J2SE to the Linux OS, and J2SE 1.5 specification lead. "The NPTL library is now available in Red Hat Linux 9 by default. This is a very exciting time for Java Linux developers."

Sun Microsystems, Inc. announced on May 19, 2003, that it has entered into a global alliance agreement with Red Hat, Inc. to distribute Red Hat's market-leading Enterprise Linux operating system, and to broaden the use of each other's technologies in the rapidly growing volume server marketplace. As part of the agreement, Red Hat will distribute Sun's Java Virtual Machine (JVM) with Red Hat Enterprise Linux, extending the reach of the world's most popular application environment. Sun will sell and support all x86 versions of Red Hat Enterprise Linux, including Red Hat Enterprise Linux AS, Red Hat Enterprise Linux ES, and Red Hat Enterprise Linux WS.

The Origins of NPTL

The old POSIX thread library ran on all major Java Virtual Machines, but with limitations. While Java technology developers could create hundreds or thousands of threads, this led to problems on IA-32, and resulted in less than stellar performance. Controlled runtimes paid a heavy price for being multithreaded. "The problems could not be solved with only slight corrections in the code," explains Ulrich Drepper, designer and original author of NPTL at Red Hat, Inc., "and by the late summer of 2002, customer requests for better threads motivated Red Hat to take action."

The biggest challenge was getting support from kernel developers, as they held the key to better thread implementations. Next, what specific kernel changes were needed? "The question was: do we stick with the 1-on-1 model, with a user kernel thread for each user-level thread, or do we use the M-on-N model, where several kernel threads collectively execute the user-level threads?" comments Drepper.

Initially, the scale tipped in favor of the M-on-N model, since on IA-32, only this model allowed developers to use the Local Descriptor Table (LDT, a CPU data structure), while still allowing the creation of any number of threads. With the M-on-N model, the number of kernel threads and user-level threads do not have to be in a fixed correlation. However, this decision was reversed when Red Hat developed and implemented the concept of a per-CPU, per-process Global Descriptor Table (GDT) entry. "This is an ingenious mechanism in which only one GDT entry is used for all threads and processes, and the value is reloaded by the kernel at each context switch," observes Drepper.

With this change in place, the road opened for 1-on-1 implementation, which meant that the design could be kept simple, since most of the needed functionality could more or less directly be mapped to kernel functionality. "The new thread library is a thin layer on top of the kernel," says Drepper. "The kernel had to be extended significantly. Half a dozen new system calls were needed, and the signal handling, along with lots of data structures and algorithms used in the kernel, had to be revised to support the huge number of threads which would be created."

"Now, finally, Linux is a viable platform for highly-threaded Java applications."

- Ulrich Drepper, designer and original author of NPTL, Red Hat

The main change made to the signal handling was the implementation of shared signal queues. "All the threads in a process share this one signal queue in addition to their own, thread-local signal queue," observes Drepper. "The shared signal queue was probably the biggest POSIX compliance problem in the LinuxThreads code."

Meeting Design Goals

It took three months to complete the first fully functional version of the new code, Native POSIX Threads Library. Several of the original design goals were met:

  • No limits on the number of threads
  • Fast thread creation
  • Fast synchronization primitives
  • Full POSIX compliance

In addition, as a bonus, a few more POSIX features which previously couldn't be implemented are now available, including inter-process synchronization primitives and named POSIX semaphores.

Since the initial NPTL release, many improvements have been made, the most important of which include:

  • Ports to SH, ia64, s390, ppc, alpha, and amd64
  • Scalability improvements for high-end machines
  • Dramatic improvement in performance of cleanup handler registration through the use of exceptions
  • Scheduler settings (priority, scheduling type) which can be used to implement parts of the Java thread class

The New with the Old

The new implementation is also binary-compatible with the old code. This has been decisively demonstrated by Sun Microsystems' J2SE 1.4.1 JRE, which runs well with NPTL.

The NPTL can now support Java implementations far better than any previous implementations. The lightweight 1-on-1 implementation is fast, robust, and POSIX-compliant, allowing a Java runtime environment to use it as directly as possible, without the additional layers of code needed for other implementations.

Internal Testing

Even though the NPTL threads library is relatively new, some applications have already shown considerable improvement when running J2SE 1.4.2 with Red Hat Linux 9 on single and dual SMP configurations, when compared with J2SE 1.4.1 and the old Linux thread library.

Internal tests reveal that performance of NPTL with a client/server application has been impressive. On a 2 X 1.6 Ghz P4 Xeon system, time to completion was 191% faster with J2SE 1.4.2 running on NPTL, compared with J2SE 1.41 running on the original Linux threads.

Some bugs have yet to be resolved. "There are currently performance bugs when running on a four-way system. However, future updates to the Java runtime and NPTL thread library are anticipated to show improvements on larger systems (four-way and above)," explains Austin.

For information on internal tests and benchmarks for J2SE 1.4.2, see:

Future Extensions to the Thread Library

Future versions of the thread library will mainly feature performance and scalability improvements, more support for NUMA machines, and new interfaces to better support higher-level languages like the Java language. "The scheduler responsible for the selection of the threads which are executed on the CPUs has all the information about the threads, and could be tuned to take this into account," explains Drepper. "Also, the kernel functionality used for the synchronization of primitive implementation will need serious scalability improvements to support large numbers of concurrently used synchronization objects, and to better support SMP and NUMA machines."

While future extensions to the thread library API might include better support for garbage collection, the code as it exists today is a huge step forward; its performance and features compare well with any other implementation. "Now, finally, Linux is a viable platform for highly-threaded Java applications," concludes Drepper.

Improvements in J2SE 1.4.2

With the advent of Sun's J2SE 1.4.2, the first JVM fully tested with NPTL has been released. The new thread library makes the code more stable, with improved performance due to faster thread creation and superior synchronization primitives.

"With the release of Red Hat Linux 9, Java technology users can now have more than 1024 threads running at the same time, which was impossible with previous releases," points out Hui Huang, lead HotSpot Linux Engineer for Sun Microsystems. The benefits do not stop there -- problems that were caused by the Linux thread signal/synchronization implementation have been eradicated, and the Java runtime is more reliable and stable.

There are many other improvements in J2SE 1.4.2. The startup time has been reduced; some applications start up 30% faster when compared to J2SE 1.4.1. The Java Virtual Machine has also been tuned to minimize contended locks. Developers can look forward to further improvements in Java 2 Platform, Standard Edition, 1.5 (J2SE 1.5).

See Also

White Paper on J2SE 1.4.2 Performance

Red Hat, Inc.

J2SE 1.4.2

J2SE 1.4.2 and J2SE 1.5

Internal Tests and Benchmarks for J2SE 1.4.2