There are five areas of information.
For additional IBM value add content.
We welcome additional tips. Send comments to us through the contact us link. Please specify performance or hints and tips in the comment on: section.
Considerations
When using the product
- Java and LE runtime options
- JCL REGION size parameter
- Java Start Up Time
- 64 Bit Java
- 64 bit Java -Xcompressedrefs and -Xlp option
- Shared Classes Group Access Examples
Java and LE runtime options
These are described in the LE Programming Reference (PDF, 5.24MB). The java executables (java, javac, javah, JZOS Batch Launcher, etc.) are built with a recommended set of runtime options.
You can use the runtime option RPTOPTS(ON) to produce a report that display the options in effect for the java SDK executable.
JCL REGION size parameter
This needs to be large enough to allow for all of the heap and stack storage requirements, plus LE and Java code, and LE internal control blocks. OutOfMemoryError is not very granular. You may be able to get further useful information by inspecting the Java stack traceback.
Java Start Up Time
When running hundreds or thousands of small Java batch jobs, the Java start up elapsed time and CPU time become an important performance measurement for many customers. Use of the following Java options makes it possible to reduce the Java startup times for applications that start a new JVM frequently:
- -Xquickstart Java option
- Shared classes and AOT Java options
Java Shared Classes and AOT Examples
You can see below that in this example, the default shared class library size of 16 megabytes was too large for the current BPXPRMxxx setting, which has resulted in an error message. This problem was caused by BPXPRMxx IPCSHMMPAGES set to 8 MegaBytes, which was less than the defalut shared class library size.
$ java -Xshareclasses:listAllCaches JVMSHRC005I No shared class caches available Could not create the Java virtual machine.
In this next java command, the -Xscmx1m option was specified to use a shared class size of 1 Megabytes. This command was successful. Note that this example requires access to a HelloWorld java program.
> java -Xscmx1m -Xshareclasses:name=cache1 HelloWorld Hello World
The following commands demonstrate how to use different shared classes with different sizes.
> java -Xshareclasses:listAllCaches Shared Cache OS shmid in use Last detach time cache1 1646599 0 Fri Jun 10 10:43:47 2009 Could not create the Java virtual machine. > java -Xscmx8m -Xshareclasses:name=cache2 HelloWorld Hello World > java -Xscmx8m -Xshareclasses:name=cache3 HelloWorld Hello World
Using the ipcs -bom command, the 1 megabyte shared memory segment is displayed for user TESTER
> ipcs -bom IPC status as of Fri Nov 14 10:52:15 2008 Shared Memory: T ID KEY MODE OWNER GROUP NATTCH SEGSZPG PGSZ SEGSZ m 8196 0x012ed3f0 --rw------- TCP DEPTD60 1 1 4K 4096 m 8197 0x022ed3f0 --rw------- TCP DEPTD60 1 1 4K 4096 m 8198 0x032ed3f0 --rw------- TCP DEPTD60 1 1 4K 4096 m 1646599 0x0100f6f5 --rw------- TESTER DEPTD60 0 256 4K 1048576 m 8200 0x0100b3f5 --rw------- TESTER DEPTD60 0 2048 4K 8388608 m 8201 0x0100bcf5 --rw------- TESTER DEPTD60 0 2048 4K 8388608
The following java commands demonstrates options to display shared class information.
$ java -Xshareclasses:listAllCaches Shared Cache OS shmid in use Last detach time cache1 1646599 0 Fri Nov 14 10:50:33 2008 cache2 8200 0 Fri Nov 14 10:51:57 2008 cache3 8201 0 Fri Nov 14 10:52:12 2008
Could not create the Java virtual machine. > java -Xshareclasses:name=cache1,printStats Current statistics for cache "cache1": base address = 0x26F00058 end address = 0x26FFFFF8 allocation pointer = 0x26FFD418 cache size = 1048488 free bytes = 604 ROMClass bytes = 1037248 Metadata bytes = 10636 Metadata % used = 1% # ROMClasses = 234 # Classpaths = 1 # URLs = 0 # Tokens = 0 # Stale classes = 0 % Stale classes = 0% Cache is 99% full Could not create the Java virtual machine. > java -Xshareclasses:name=cache2,printStats Current statistics for cache "cache2": base address = 0x26F00058 end address = 0x276FFFF8 allocation pointer = 0x2703F508 cache size = 8388520 free bytes = 7067020 ROMClass bytes = 1307824 Metadata bytes = 13676 Metadata % used = 1% # ROMClasses = 306 # Classpaths = 2 # URLs = 0 # Tokens = 0 # Stale classes = 0 % Stale classes = 0% Cache is 15% full Could not create the Java virtual machine.
The following java command demonstrates how to destroy or remove a shared class library. In this example the shared memory segment for the shared class is also removed. It should be noted that the share memory for java shared classes is not removed when the JVM terminates. The following java command with the destroy option must be issued to remove the shared class and its shared memory as shown below.
> ipcs -bom IPC status as of Fri Nov 14 10:52:15 2008 Shared Memory: T ID KEY MODE OWNER GROUP NATTCH SEGSZPG PGSZ SEGSZ m 8196 0x012ed3f0 --rw------- TCP DEPTD60 1 1 4K 4096 m 8197 0x022ed3f0 --rw------- TCP DEPTD60 1 1 4K 4096 m 8198 0x032ed3f0 --rw------- TCP DEPTD60 1 1 4K 4096 m 1646599 0x0100f6f5 --rw------- TESTER DEPTD60 0 256 4K 1048576 m 8200 0x0100b3f5 --rw------- TESTER DEPTD60 0 2048 4K 8388608 m 8201 0x0100bcf5 --rw------- TESTER DEPTD60 0 2048 4K 8388608 > java -Xshareclasses:name=cache1,destroy JVMSHRC010I Shared Cache "cache1" is destroyed Could not create the Java virtual machine. > ipcs -bom IPC status as of Fri Nov 14 10:57:31 2008 Shared Memory: T ID KEY MODE OWNER GROUP NATTCH SEGSZPG PGSZ SEGSZ m 8196 0x012ed3f0 --rw------- TCP DEPTD60 1 1 4K 4096 m 8197 0x022ed3f0 --rw------- TCP DEPTD60 1 1 4K 4096 m 8198 0x032ed3f0 --rw------- TCP DEPTD60 1 1 4K 4096 m 8200 0x0100b3f5 --rw------- TESTER DEPTD60 0 2048 4K 8388608 m 8201 0x0100bcf5 --rw------- TESTER DEPTD60 0 2048 4K 8388608
64 Bit Java
Use of 64 bit Java may make it possible to define large Java heap size to avoid out of virtual memory conditions and improve application reliability. Large Java heaps also means that Garbage Collection will occur less frequently, which may improve your applications performance. Use of 64 bit Java Compress References option -Xcompressedrefs and large page option -Xlp in IBM Developer Kit for Java 6 will improve performance of 64 bit Java significantly.
Examples First Time Using 64 bit Java
To be able to run 64 bit Java, the memory limit or memlimit for memory above the bar must be sufficient to run the 64 bit application. Before attempting to use 64 bit Java for the first time on z/OS, check that the memlimit "memory above the 2 Gigabyte bar" is not zero by using the ulimit command as shown below. In this example the memory above the bar is 1000 megabytes. Your configuration may be different.
> ulimit -a core file 8192b cpu time unlimited data size unlimited file size unlimited stack size unlimited file descriptors 1500 address space unlimited memory above bar 1000m
The following 64 bit Java command is invoked to display the java version. The following command displays "s390x-64" , which means the 64 Bit Java is being run.
> java -version java version "1.6.0" Java(TM) SE Runtime Environment (build pmz6460sr5-20090604_01(SR5)) IBM J9 VM (build 2.4, J2RE 1.6.0 IBM J9 2.4 z/OS s390x-64 jvmmz6460sr5-20090519_35743 (JIT enabled, AOT enabled J9VM - 20090519_035743_BHdSMr JIT - r9_20090518_2017 GC - 20090417_AA) JCL - 20090529_01
Next example will use -verbose:gc java command option to display the default Java heap size values. In this example maxHeapSize value is 0x20000000 or 512 megabytes.
> java -verbose:gc -version <initialized> <attribute name="gcPolicy" value="-Xgcpolicy:optthruput" /> <attribute name="maxHeapSize" value="0x20000000" /> <attribute name="initialHeapSize" value="0x400000" /> <attribute name="compressedRefs" value="false" /> <attribute name="pageSize" value="0x1000" /> <attribute name="requestedPageSize" value="0x1000" /> </initialized>
The next examples demonstrates changing the memlimit for above the bar storage from 1000 megabytes to 200 megabytes using the ulimit -M option. After setting 200 megabyte above the bar storage, the 64 bit java command is invoked with default heap size of 200 megabytes. As expected the java command fails. Note this example requires access to a Java HelloWorld program.
> ulimit -M 200 > ulimit -a core file 8192b cpu time unlimited data size unlimited file size unlimited stack size unlimited file descriptors 1500 address space unlimited memory above bar 200m > java HelloWorld CEE0814S Insufficient storage was available to extend the stack. [1] + Done(139) java HelloWorld 16908772 Segmentation violation /PRIPKC/J6.0_64/bin/java
If the the first time use of 64 bit Java fails, the first thing to check is ulimit -a memory above the bar storage is sufficient to run a java application.
The next example shows invoking java command for HelloWorld wth a smaller maximum heap size value of 100 megabytes to compensate for the 200 megabyte memory above the bar storage. As you can see this HelloWorld example was successful with the smaller Java heap size.
> java -Xmx100M HelloWorld Hello World
64 bit Java -Xcompressedrefs and -Xlp Options
As mentioned above, the 64 bit java command provides two options that can significantly improve performance. The compressed references and large pages features were added to the IBM Developer Kit for Java 6, 64-bit edition, J9 Java virtual machine (JVM) and Just-in-Time (JIT) compiler to provide relief for memory footprint growth incurred when migrating from a 31-bit JVM to a 64-bit JVM. This growth in footprint typically increases system memory requirements while also regressing throughput performance. Using the compressed references and large pages features provides 64 bit Java performance that may be equal to 31 bit Java performance for some applications.
Hints: The -Xcompressedrefs with a 2048 megabyte heap size is a performance sweet spot, which may be a good starting point when tuning a 64 bit Java application for the first time. Also note that even though you may specify the -Xlp option, it is possible that Java may use the smaller 4096 byte pages, when large pages are either not configured or not enough large pages are available.
The following white paper shows that it is possible to recover the 31-bit footprint and throughput performance using these 64-bit new options and heap sizes up to 30 GB. This paper also reviews the advantages and disadvantages of using 31-bit SDK and 64-bit SDKs, provide a brief implementation overview, and discuss the performance characteristics of various combinations of heap sizes and Java options. All developers are encouraged to read through this article, but the intended audience is enterprise application developers who are deploying Java workloads on the IBM System z10 mainframe.
Examples Using -Xcompressedrefs and -Xlp
This example below uses the sweet spot of 2 Gigabyte heap size ( -Xmx2048m ) with Compressed References. The -verbose:gc option shows that the compressedRefsShift value is zero. This means that zero shifts are required when converting the 4 byte compressed reference addresses to 8 bytes. This zero shifts is why this is a performance sweet spot. Also note that compressedRefs value= true, which means compressed references are enabled.
> java -verbose:gc -Xcompressedrefs -Xmx2048m -Xms2048m HelloWorld <initialized> <attribute name="gcPolicy" value="-Xgcpolicy:optthruput" /> <attribute name="maxHeapSize" value="0x80000000" /> <attribute name="initialHeapSize" value="0x80000000" /> <attribute name="compressedRefs" value="true" /> <attribute name="compressedRefsDisplacement" value="0x0" /> <attribute name="compressedRefsShift" value="0x0" /> <attribute name="pageSize" value="0x1000" /> <attribute name="requestedPageSize" value="0x1000" /> </initialized>
In the next example a 3Gigabyte heap size is used. In this example you see a compressedRefsShift value of 1 is shown. This means a shift by 1 instruction must be performed every time a 4 byte compressed reference address is converted to 8 bytes.
> java -verbose:gc -Xcompressedrefs -Xmx3072m -Xms3072m HelloWorld <initialized> <attribute name="gcPolicy" value="-Xgcpolicy:optthruput" /> <attribute name="maxHeapSize" value="0xc0000000" /> <attribute name="initialHeapSize" value="0xc0000000" /> <attribute name="compressedRefs" value="true" /> <attribute name="compressedRefsDisplacement" value="0x0" /> <attribute name="compressedRefsShift" value="0x1" /> <attribute name="pageSize" value="0x1000" /> <attribute name="requestedPageSize" value="0x1000" /> </initialized>
The large page example below shows the option -Xlp for large 1 megabyte pages is specified. Here you can see that the requested PageSize value of 0x100000 was requested but the pageSize value=0x1000 or 4096 bytes were actually used. Its possible other JVM processes were using all the system wide configured large pages or large pages were never configured on this system. Although large pages were not used, the program HelloWorld ran successfully with 4096 byte pages.
> java -verbose:gc -Xlp HelloWorld <initialized> <attribute name="gcPolicy" value="-Xgcpolicy:optthruput" /> <attribute name="maxHeapSize" value="0x20000000" /> <attribute name="initialHeapSize" value="0x400000" /> <attribute name="compressedRefs" value="false" /> <attribute name="pageSize" value="0x1000" /> <attribute name="requestedPageSize" value="0x100000" /> </initialized> Hello World </verbosegc>
Shared Classes Group Access Examples
On Linux®, AIX®, z/OS®, and i5/OS® platforms, if multiple users in the same operating system group are running the same application, use the groupAccess suboption, which creates the cache allowing all users in the same primary group to share the same cache. If multiple operating system groups are running the same application, the %g modifier can be added to the cache name, causing each group running the application to get a separate cache.
Note in the example below two shared classes are created. One that is shared with other JVMs in the same group and another that is shared with with JVM using the same user ID.
> java -Xscmx8m -Xshareclasses:groupAccess,name=%gcache5 HelloWorld Hello World > java -Xscmx8m -Xshareclasses:listAllCaches Shared Cache OS shmid in use Last detach time DEPTD60cache5 73739 0 Fri Mar 2 13:59:01 2007 > java -Xscmx8m -Xshareclasses:groupAccess,name=cache5 HelloWorld Hello World > java -Xscmx8m -Xshareclasses:listAllCaches Shared Cache OS shmid in use Last detach time DEPTD60cache5 73739 0 Fri Mar 2 13:59:01 2007 cache5 204810 0 Fri Mar 2 14:01:40 2007 > id uid=258(TESTER) gid=0(DEPTD60
Performance
For developing and running applications
Garbage Collection
One of the great benefits of the Java platform is that it takes care of much of the work of garbage collection for you, but there are occasions when you still want to tweak the way garbage collection takes place. With the latest Java technology implementation from IBM, you can choose among several garbage collection policies and tune the size of your heap to help obtain the optimal performance out of your application.
For a better understanding about Java Garbage collection policies see the following links:
Java technology, IBM style: Garbage collection policies, Part 1
Java technology, IBM style: Garbage collection policies, Part 2
The IBM Monitoring and Diagnostic Tools for Java™ - Garbage Collection and Memory Visualizer is designed to help diagnose and analyze memory-related Java performance problems. For more details see the following link:
Java diagnostics, IBM style, Part 2: Garbage collection with the IBM Monitoring and Diagnostic Tools for Java - Garbage Collection and Memory Visualizer
For 64 bit Java applications, Java 6 provides the -Xcompressrefs option, which will significantly reduce the size of the Java heap storage required. See the section on 64 Bit Java.
JVM
The following is a list of performance suggestions for the Java Virtual Machine (JVM) runtime environment:
- Keep Current with SDK releases.
Although Java has matured significantly over the last few years, it is a relatively new technology. Almost every release of the SDK has a double digit performance enhancements. In some case PTFs have double digit performance enhancements. By keeping current with the latest release you will be able to take advantage of this progress. - Prudent use of Zip and Jar files can improve load time.
Zip and Jar files can be used to combine many class files into one file for easier loading or file transfer. When done properly, this can improve application load time. However, avoid adding unneeded class files which will increase file size and increase memory usage. One common mistake is to produce a zip file of every utility and builder class when the application may need only a small proportion of the class files to execute. This results in increased load time. - Reorder the order in CLASSPATH
When the JVM is looking for a class, it searches the directories in the order they are given in CLASSPATH. You can improve the start-up times of your Java applications by reordering the paths in the CLASSPATH environment variable by placing the most used libraries earlier in the CLASSPATH.
z/OS UNIX System Services (USS)
The JVM uses UNIX System Services for z/OS (USS) for base operating system functions. For this reason, USS must be correctly installed and tuned in order to get optimum performance from the JVM. See USS performance for detailed tuning suggestions.
For additional information, see:
A number of Unix based tools for z/OS are available for free via download. Some of these are Java specific. These tools were designed for OS/390 UNIX, by IBM developers and testers. There are no warranties of any kind, and there is no service or technical support available for these from IBM. See the z/OS UNIX Tools .
Applications and Environments
For developing and running your applications in z/OS
- Java Interoperability: support for Java 5 and Java 6
- ASCII to EBCIDIC
- JAR file considerations
- z/OS UNIX System Services (USS)
- Language Environment (LE)
Java Interoperability: support for Java 5 and Java 6
In V4.2, Enterprise COBOL applications using object-oriented syntax for Java interoperability can now run with Java 5 or Java 6. See the Cobol references below:
http://www-01.ibm.com/software/awdtools/cobol/zos/library/
ASCII to EBCDIC
One important aspect of the System z environment that can sometimes raise portability issue with Java code is that z/OS uses the EBCDIC character encoding instead of the more common ASCII. Within the scope of the JVM, all character and string data is stored and manipulated in Unicode, and I/O data outside of the virtual machine (disk, network, and so forth) is converted to the native platform encoding. However, Java applications that implicitly assume ASCII in specific situations might require some alterations to run as expected under z/OS.
There are a number of environmental tricks that are often useful to test whether implicit ASCII assumptions are in effect. For instance, for config files read in during start-up (or other 'adminstrative' file manipulation), you can use a simple command-line utility to convert those files to the appropriate encoding that you require.
In some cases, changing JVM properties can also allow successful functionality tests, but because this can produce other side effects, the long term solution is sometimes best addressed in code. The Java language contains the abstractions necessary to handle the switch between character encodings. Most important are the various Reader and Writer classes in the java.io package, which provide alternate constructors with a specified codepage. This mechanism is used for internationalization support, and it can also be used to force ASCII (or other) I/O where required. It is important to consider that all I/O does not need to be overridden; for example, character output to the display should remain in the native encoding.
In addition to the Reader and Writer classes, there are a few specific situations that might require additional care. For example, there is an overloaded getBytes() method in the String class that takes an encoding as an additional parameter. This is useful for direct string manipulation when implementing custom data streams or network protocols directly in Java.
Some Java applications explicitly assume ASCII encoding and therefore require some alterations to run as expected under OS/390. For example, a platform neutral application might have hard coded dependencies, such as literals in ASCII.
In general, straightforward workarounds are available for character encoding problems. Some encoding problems are not visible to the application because they are handled within products running on OS/390. An example of this is Java Database Connectivity (JDBC).
It is often best to deal with codepage issues by running the JVM with default encoding of ASCII (-Dfile.encoding=ISO8859-1) and then to specifically call out the codepage that you need when you are writing to MVS files and datasets that are in EBCDIC. This makes porting of code easier, which is a reason Websphere now runs this way.
For your information, the JZOS function now incorporated into z/OS Java SDK5 and SDK6 products may also help in ASCII-EBCDIC questions. The JZOS ZUtil class has a method "getDefaultPlatformEncoding()" that returns the EBCDIC codepage that is being used by the process running the JVM. Also, the FileFactory class can be used to read and write text files - if the file is a //DATASET name then JZOS uses this encoding under the covers automatically.
For more information, see JZOS Java Launcher and Toolkit Overview .
JAR file considerations
A jar is an archive of files used by a java applet. Many or all of the files that an applet needs can be combined into a single jar file, which an appletviewer can download in a single http request.
We expect that jar files downloaded from other platforms will contain text data in ASCII (8859-1), and therefore have enabled the appletviewer to expect text files in a jar file to be in ASCII. This means however, that if the jar tool is used on z/OS to create a jar file, then text files must be converted to ASCII before being added. Of course this also means that any jar files you create on z/OS can be transported and used on other platforms. Equally, any text files extracted from a jar file will not be converted from their original encoding.
Language Environment (LE)
The JVM uses LE for runtime language services. More information can be found at the LE website. For additional Java information, see Java and LE runtime options
Troubleshooting
Helpful hints about what you can do if you have a problem
IBM JVM Diagnostics Guides
Diagnostics Guides are available. The diagnostics guide tells you about the way the IBM Virtual Machine for Java works, debugging techniques, and the diagnostics tools that are available to help you solve problems with Java Virtual Machines.
These guides include sections on the garbage collector, the JIT compiler, the class loader, the ORB and covers many aspects of problem determination in all the supported platforms.
They also reflect changes to the JAVA_DUMP_OPTS environment variable that are introduced into this service refresh, including suppression of dumps.
Information on fonts for z/OS Java product is available to provide some guidance. There have been occasional questions about usage of customer provided fonts with the z/OS Java product.