- Turbo Java in ADCD
Turbo and ADCD is a bit of an oxymoron. Although ADCD is a fully functional z/OS operating system, the primary architecture it executes under is x86. This is achieved with zPDT, and this combination is far from being synonymous with the word Turbo. Performance of Java in such environments, as many already know, is not optimal so when you have multiple heavy Java applications or subsystems trying to startup simultaneously on an x86 machine, CPU fans are the only thing running in Turbo! It’s not all bad news though, and there is some relief.
First off, I’m not proclaiming to have found something new here, rather I’m making use of existing features of z/OS and Java that have been around for some time. I’m merely highlighting some specific uses of these features in ADCD, as they have a very significant positive impact.
z/OS Explorer, z/OS Connect, z/OSMF and z/OS Debugger profile service are a few of the system tasks that make heavy use of Java, and if you are running any or all of these subsystems (like I am), then tweaking a few Java options can result in cutting the startup times of these tasks in half, and in some cases even more. Using the options described below may also help with normal everyday usage of these software products too, although I’ve not tested this so as always YMMV.
How to Give Java A Boost
Spoiler alert, there’s no single Java option that’s the panacea here. JAVA_OPTS=-XrunReallyfast is an undocumented option, and unfortunately is not a real option at all, so sadly doesn’t work. It was worth a try.
What DOES actually work, and documented too are:
-Xms, -Xmx, -Xshareclasses, -Xquickstart, and -Xlp
I also make use of the Java cache utilities (snapShotcache, restoreSnapshot).
The Java Options used in my testing:
-Xscmx50m (I used 150M for z/OSMF and 30M for z/OS Explorer)
I’m not going to document what all these options mean in this post as I am far from a Java expert, nor am I a Java programmer. I would welcome any comments on these options or additional options that others feel will help out in any way. There is plenty of documentation on these options here => click
One important point I’ll raise is you can tune/monitor the size of your Java cache via the -Xscmx option and use of the printStats cache utility to see how it’s doing.
Z/OS Large Page Support
z/OS Large Page support (needed to support the -Xlp Java options listed above) is another area of opportunity. I’ve yet to actually crunch real numbers to substantiate if there was any significant difference with and without Large Page support, but as someone that likes tweaking options, I’m convinced it helped! I can say with confidence that the other Java options/features offer a greater impact. You can, of course, omit the -Xlp options and not enable z/OS Large Page support and still realize significant improvements. If your z/OS system has less than 8GB of memory configured then you likely will want to avoid enabling LFAREA.
Since enabling z/OS Large Page support was dead-easy, I did it. I enabled only 1MB pages, since adding 2GB pages requires considerable memory. For 1M pages I added LFAREA=(1M=(15%,0%),NOPROMPT), to my IEASYSxx member of PARMLIB and IPL’d z/OS. I thought 15% seemed like a good start and with 8GB of memory configured for my z/OS system, 612-1MB Pages were created. You can increase or decrease the percentage for 1MB pages if you desire by adjusting the % up or down. If time permits I may test timings with and without Large Page support. UPDATE .. I did some minor testing with and without Large Pages and indeed it did shave off a couple of seconds!
Setup and Testing
For testing these “Turbo” features, I made use of z/OS Connect (ZOSCSRV task in ADCD) simply because it displays a message telling me how long it takes to startup, so that provides real quick-and-easy eye test to see how the tweaks are helping.
The setup for ZOSCSRV is as follows.
I created a new “Java options” file:
/etc/zoscsrv.options – contains all the Java options listed above
Since I store all my Java cache files in /javasc I needed to create this directory as well (with permissions 777). The Java cache utilities create subdirectories under this one. Alternatively you can use a different directory as you wish (like /tmp). If using large caches, this directory should probably be backed by it’s very own ZFS. The z/OSMF cache I create is 150MB, and all the others are around 30M or 50M, and so with everything taking snapshots to this directory, means it should be more than the sum of all caches since there are also some other files written here by Java itself.
The ZOSCSRV started task JCL was modified to specify a new environment variable, which pulls in the Java options file. The following was added to STDENV DD statement:
In addition, a new step was added to the ZOSCSRV started task JCL, at the very beginning, which performs the restoreFromSnapshot Java cache utility.
//STEP1 EXEC PGM=IRXJCL,PARM=’JCACHER zcn restoreFromSnapshot’
//SYSEXEC DD DSN=ADCD.Z24A.SYSEXEC,DISP=SHR
//SYSTSPRT DD SYSOUT=*
As you might guess, restoreFromSnapshot restores the in-memory Java cache from a Snapshot previously taken of the cache. This Snapshot is written to disk in (/javasc/zcn/javasharedreources/* in my example). The critical step here is you have to take the Snapshot of the cache before you shutdown your system. If there is an old cache Snapshot lying around, it will be overwritten when a new Snapshot is performed. If there is no Snapshot to restore, the worst thing that happens is performance reverts back to how it was without having the in memory cache pre-built. There is still lots of benefit from the other options still in play.
From the above JCL step added, you can see I am running something called JCACHER. This is a simple REXX program I use to call the Java cache utilities. JCACHER is very much a work-in-progress. The source for JCACHER is here => JCACHER_SOURCE
There are issues with getting Return codes from Java when calling the cache Utilities (they always return RC=1) so this means parsing output to determine results … yuck… I smell an RFE for the Java developers.
Rather than using a REXX script like JCACHER, you could just as easily create and call a shell script and run it via BPXBATCH to do the same thing, but I prefer REXX in TSO as my “go-to” whenever possible.
Without JCACHER or some other tool you create, you will need to resort to manually running restoreFromSnapshot (before starting tasks) and snapShotcache (before system shutdown) from the OMVS shell, for example:
Obtain Stats on your cache by using this command:
So after putting all this into action….
Here’s the results for z/OS Connect:
+CWWKF0011I: The defaultServer server is ready to run a smarter
planet. The defaultServer server started in 66.626 seconds.
+CWWKF0011I: The defaultServer server is ready to run a smarter
planet. The defaultServer server started in 189.918 seconds.
That is quite the improvement, almost 3 times faster !!!
The above test was run on a P53 laptop where z/OS was configured with 3 CP’s and 8GB memory. The IPL also included startup of z/OSMF, z/OS Explorer and z/OS Debugger Profile service simultaneously with z/OS Connect, which were all heavy on Java. The timings you might experience could be better/worse depending on what other system tasks you are starting by default, what hardware you are running on and what your zPDT configuration is.
For z/OSMF and z/OS Explorer you can use these options, but if you do remember to create directory /javasc with permissions 777.
z/OSMF: add the below to=> /var/zosmf/configuration/local_override.cfg
z/OS Explorer: add to /etc/zexpl/rse.env
_RSE_JAVAOPTS="$_RSE_JAVAOPTS -Xms256m -Xmx512m -Xquickstart -Xshareclasses:nonFatal -Xshareclasses:groupAccess"
_RSE_JAVAOPTS="$_RSE_JAVAOPTS -Xshareclasses:cacheDirPerm=0777 -Xscmx30m -Xshareclasses:cacheDir=/javasc/rse,name=rsecache"
_RSE_JAVAOPTS="$_RSE_JAVAOPTS -Xlp:objectheap:pagesize=1m,warn,pageable -Xlp:codecache:pagesize=1m,pageable"
The opinions, views or recommendations expressed in this blog are mine only and not those of IBM, or any other corporate entity.