Performance and Scalability Enhancements in Java 5
Java applications get considerable support from JVM in managing the runtime performance of applications. First and most differentiating thing in Java, as compared to other languages, is garbage collection (GC). Developer of an application does not need to worry about the memory clean up in general, leaving the developer to focus on functional part of the application mainly. In addition to the default features, there are many configurable parameters which can be used to tune the JVM to make the application perform better. These parameters are also dependent on the underlying operating system i.e. there are different parameters of Windows, different parameters for UNIX and so on. These controllable parameters are determined considering how the operating system allows to control its processing externally (in this case to JVM).
In this major release of Java, i.e. Tiger release, there is more focus on performance and scalability improvement of applications running in JVM. Java is taking some more bourdon off our head. This will also reduce the performance problems faced by the applications. In the following discussion, we take the changes one by one and see what difference those are causing to our life as a developer (and even to other roles).
Ergonomics:
This is health of JVM, i.e. how good JVM is operating to make the application perform better. This also involves optimal use of the operating system resources to get the best results. In version 1.4, we have command line options (can retrieved using ‘java -X(X)’ command) to change and optimize performance of JVM according to application needs. I am sure most of us never touched these options unless the application performance was not meeting requirements. So everything needs to be working fine in default mode. This need is identified and address in Java 5. Following important tuning attributes are changed as compared to 1.4 to fulfill this requirement.
- Throughput garbage collector over serial garbage collector
- Heap sizes
- Initial heap size: 1/64th of physical memory up to 1 GB instead of 4 MB
- Maximum heap size: 1/4th of physical memory up to 1 GB instead of 64 MB
- Server runtime compiler instead of Client runtime compiler (for 64 bit machines on any operating system)
All this has become possible because the general hardware configuration has also moved from few MB memory machines to few GB machines. Now Java treats the machines as server machines having 2 or more processors and 2 or more GB memory, and it tries to utilize it accordingly to achieve better output from JVM. If the configuration is below then the default JVM configurations also change accordingly.
In Java 5, GC itself can be tuned. Previous versions had little control over it, meaning GC pitched in when there was a need of memory. But now we can set two parameters which directly result in performance change.
- Maximum pause time goal – pause GC activity for given time so that the processing power is mainly used for application. This goal has a constraint of the memory requirement by application, i.e. if the application falls short of memory, then GC will start operation instead of achieving goal. (This option can be used to set the pause time goal -XX:MaxGCPauseMillis=<nnn>)
- Application throughput goal – we can specify the throughput expectation (time spend in GC / time spend outside GC) for the JVM. (-XX:GCTimeRatio=<nnn>)
- Footprint goal - This is the amount of memory used by JVM. When above two goals are met then JVM tries to reduce the heap memory utilized and the footprint gets reduced. (There is something more to reduce memory footprint discussed below.)
It is not necessary that the goals will be achieved always, but at least an attempt is made to achieve these goals. We can say that JVM is getting intelligent here and trying to optimize itself runtime.
High Precision Timing:
New method System.nanoTime() to get more accurate time. Mind you, time is retrieved from operating system, hence the precision will also be function of the operating system.
StringBuilder Class:
String processing has always been a pain area. First the String operations are mutable creating unnecessary objects, and increasing load on garbage collector and second option StringBuffer is synchronized eating up more time. Now StringBuilder class does the same job as StringBuffer but without synchronizing, that is why it is faster. In the string operations where we don’t need synchronization, or already the program runs in single threaded mode, we can definitely go for this performing alternative StringBuilder.
Java 2D Technology Improvements:
Java 2D technology is used for 2D graphics and imaging covering line art, text and images. Java 5 provides many changes to enhance this technology. This technology already involves graphical objects consuming lot of memory, hence naturally being slow. These programs involve a lot of interaction with the operating system also, which degrade performance further sometime. Hence following features are provided which will speed up working with Java 2D.
- Caching all buffered images: All managed images work better than un-managed images. In Java 5 all images created using BufferedImage class are managed images and these images will perform better.
- Methods for Controlling Hardware Acceleration of Images: This is a bug fix which expects additional methods for hardware accelerating images. Two additional methods are introduced. The function of these methods depends on how hardware supports image acceleration.
- Support for Hardware-Accelerated Rendering using OpenGL: OpenGL based pipeline is included for rendering text, images as well as complex transforms like paints, composites and clips.
- Solaris and Linux Support for CUPS Printers: Common Unix Printing System printers can be used by Solaris and Linux.
- Bicubic Interpolation: Bicubic interpolation is interpolation of data on regular 2 dimensional grid. This support is added to Java 5.
- Creating Fonts from Files and Streams: Font objects can be created directly from Type 1 fonts even from files (containing Type 1 fonts or Truetype font data).
- Improved Text Rendering Performance and Reliability: Changes to improve text rendering.
- Multilingual Text Rendering: This is to render multiple fonts supported by the operating system.
Image I/O Improvements:
Under this section there are two important changes -
- Image I/O Support for BMP and WBMP Formats: These additional formats are supported.
- Improved Performance: The Image I/O system’s performance and memory usage in reading and writing JPEG images is improved in this release.
Thread Priority on Solaris Platform:
This is an important fix in multithreading implementation. In Java, we set the thread priority to execute concern thread first as compared to other low priority threads. This priority change in followed well inside JVM, but there is operating system which finally controls the game by having full control on resources. Because of this sometimes the medium priority native operating system threads may get higher priority over top priority JVM threads. The mapping of JVM priority with the operating system priorities will determine whether the threads will get priority over native threads or not. In Java 5, there is a change as far as Solaris OS is concern, JVM maps the priorities 10 through 5 to the highest priorities of native threads, while priorities 1 through 4 are mapped to lower native priorities. Thus a highest priority thread of JVM will compete with a highest priority thread of OS, and a normal priority i.e. 5 thread will compete with corresponding native priority thread. This approach brings Java applications to run with equal priorities against the native jobs.
Class Data Sharing:
This has to do with the JVM start up process. JVM start up process is reading many files (containing classes) from the Java library as well as system library. All these loaded classes are kept in memory to make readily available for the programs running in JVM. All such classes determine memory footprint of JVM. In JVM 5, the changed approach tries to share the class data after installation during subsequent uses. Here are the steps mentioning how this sharing happens.
- Installation process loads a set of classes from system jar file.
- After loading it stores this private, internal representation of loaded classes in a file.
- When JVM starts, it shares this archived file by mapping to it.
- Also during subsequent start ups the class loading step shares this file.
The benefit is – every time you start the JVM, you don’t need to load all the classes, instead the classes are used from the archived file. This means you have load less number of classes at start up every time. It reduces the memory footprint of JVM and improves performance. Same thing also happens in case of processes that share these classes. Last thing – class data sharing is configurable using -Xshare parameter. You can set it on/off/auto as per requirement.
Monitoring and Management:
In Java 5.0, Java Virtual Machine Monitoring and Management API enable managing and monitoring of underlying operating system.
There are many more minute modifications which are improving performance of Java 5 applications.
- Optimization for x86/x64
- Hotspot Reliability
- Concurrent Low Pause Garbage Collection Improvements
- Few New Platform Support
Summary:
Java 5.0 enhances Java to improve garbage collection, APIs for String operations, JVM start up and also for multithreading. These changes will definitely help a developer to write performing operations and focus on functional part of application development.
Previous Next
If you enjoyed this post, please consider to leave a comment or subscribe to the feed and get future articles delivered to your feed reader.
