Calculating storage requirements for JVM servers
To start one or more JVM servers in a CICS® region, you must ensure that there is enough free storage available for each JVM to use. CICS and other products that are running in the same region might require a considerable amount of z/OS® storage. CICS allocations such as DSALIM and EDSALIM affect storage availability and might be over-allocated compared to the peak requirements.
About this task
The storage that is required for a JVM server does not come from CICS DSA storage. Some is managed by the Language Environment® handling requests such as malloc() issued by C code, and some are managed directly by the JVM that uses z/OS storage management requests such as IARV64. The Language Environment uses z/OS storage services. The release of the JVM in use has a bearing on whether Language Environment or z/OS manage certain types of storage. For example, the storage for the Java™ Heap might be managed by Language Environment in one JVM release but managed by z/OS in another.
There are a few user configuration options that directly specify the amount of storage for a JVM. For example, the Java command line option -Xmx3G requests 3 GB of 64-bit storage for the Java Heap.
The amount of storage that is used outside of the Java Heap is a function of what the JVM server is asked to handle in terms of the workload and Java classes that are run. This might be a considerable amount. A JVM server might be configured to handle anything from a relatively simple to a complex workload. An example of a complex workload is when a CICS Liberty JVM server is started. Even a simple workload might require many internal JVM processes that can require a considerable amount of storage. The dynamic nature of this type of storage makes an accurate estimate impossible.
JVM server dynamic storage requirements
The first JVM that starts causes the amount of storage to be defined for the USS SHRLIBRGNSIZE parameter to be allocated within 31-bit ELSQA storage. This reduces the amount of available 31-bit user region storage. The D OMVS,L command output shows the value of SHRLIBRGNSIZE.
4K of 24-bit storage is required for each JVM thread, and a single JVM server might legitimately start many more than 100 threads even before you consider the number of CICS managed JVM server threads defined by THREADLIMIT. In addition, UNIX System Services require 256 K of contiguous 24-bit storage during the process of creating a new thread.
A single JVM server might use several 100 MB of 31-bit user region storage, for example, the JIT compiler alone might use up to 128 MB in z/OS subpool 1 or 2. On top of the JIT usage, you must add other dynamic requirements of the JVM and all products in the region that interact with the JVM. The Java command line option -Xcompressedrefs might be responsible for much of the 31-bit storage usage. From Java 7.1, -Xcompressedrefs is the default, so -Xnocompressedrefs might need to be specified to reduce the 31-bit storage usage to avoid 878-10 abends.
The amount of 64-bit z/OS storage that can be used by a JVM server in addition to the Java Heap might range between 100 MB - 1 GB or higher. In addition to this, up to 36 MB per thread is allocated. The amount is calculated as the DFHAXRO STACK64 maximum stack size + 4 MB. For example, if STACK64(1 M,1 M,16 M) is used, the value is 16 MB + 4 MB, hence 20 MB is allocated. All of this counts towards the CICS view of MEMLIMIT when GDSA expansion is required. But for the z/OS MEMLIMIT check, a value between 3 MB and the allocated size is counted depending on the peak requirement for the Usable area of the stack.
The biggest challenge to running a JVM server is the amount of 31-bit, and possibly 24-bit, storage that is required as that is always limited to some extent. 64-bit usage is limited by MEMLIMIT, and can be set to an artificially high value initially and reduced if required.
It might be possible to significantly reduce the amount of storage that is used by tuning Language Environment and Java options.
It is possible to see Language Environment owned 31-bit z/OS storage subpool 1 usage growing over time, and while it might look like a Storage Leak, that is not necessarily the case. In most instances, both the growth and the total amount of subpool 1 storage can be corrected by tuning the Language Environment HEAP64 runtime option 31-bit parameters, or by setting -Xnocompressedrefs, or both. Similarly, growth over time in 64-bit storage might have the same underlying cause and can be corrected by tuning the Language Environment HEAP64 64-bit parameters.
The following procedure aims to provide a simple estimate for the initial sizing, and room for expansion of both 31-bit and 64-bit storage must be possible to mitigate against an estimate that is too small. DFH0STAT reports show the actual storage usage when a JVM server is active.