Calculating storage requirements for JVM servers

To run a JVM server successfully in a CICS region, you must ensure that enough free z/OS storage is available for both the JVM and its deployed applications to use.

About this task

The storage that is required for a JVM server, and the Java applications in it, does not come from CICS-managed storage areas such as the DSA, EDSA, or GDSA. Some storage areas are managed by the Language Environment handling requests, such as malloc() issued by C® code. The remaining storage areas are managed directly by the JVM, by using z/OS storage management requests such as IARV64. Both of these storage area management types use storage from the available private areas.

It is important to ensure that sufficient unallocated user region storage is available in the 24-bit, 31-bit, and 64-bit addressing ranges. The JVM server initialization fails with message DFHSJ0914E if any of the following minimum storage requirements are not met at the time of initialization:
  • At least 512K of unallocated 24-bit z/OS® storage
  • At least 256K of contiguous area available in unallocated 24-bit z/OS storage
  • At least 32,768K of unallocated 31-bit z/OS storage
  • At least 1G of unallocated 64-bit z/OS storage

In addition, CICS cannot use its short-on-storage mechanism when user region storage is running low.

The major Java components that allocate z/OS storage areas are as follows:
  • Java heap
  • Loading of Java classes
  • JIT compilation caches
  • Native stack
  • Java monitors
  • Java threads
  • UNIX shared libraries

The Java heap is a contiguous pre-allocated block of 64-bit storage that is used to store the runtime data area for all objects and arrays. It is managed by the JVM garbage collection process, and its size can only be modified if the JVM is restarted. The other JVM storage areas are more dynamic in size and their size can vary depending on usage. In addition to the storage areas that are allocated by the JVM, you must also consider other components that use private area and interact with the JVM such as JDBC type 2 drivers, IBM® MQ Java adapter, or third-party tools.

To estimate the amount of storage used by the JVM in the different private areas, you can use the following procedure.

Procedure

  1. Calculate your 24-bit storage.

    Each JVM thread requires 4 KB of 24-bit storage. A single JVM server can start more than 50 background daemon threads; this number does not include the number of CICS-managed JVM server threads defined by the JVMSERVER THREADLIMIT attribute. If you are using a Liberty JVM server, the number of daemon threads can be 100 or greater.

    UNIX System Services temporarily requires 256 KB of contiguous 24-bit storage during the process of creating a new thread. The minimum 24-bit requirement is calculated as follows:

    256KB + (4KB * number_of_threads)
  2. Calculate your 31-bit storage.

    Multiple JVM components can allocate storage from the 31-bit private area that includes loading of Java classes, CICS control blocks, Java thread stack, the JIT compiler, and the USS dynamic link library (DLL) files used by the JVM.

    1. Java class loading

      By default, CICS JVM servers with -Xmx (heap) values of 57GB or less use Java compressed references. Compressed references instruct the JVM to create smaller objects, and having smaller objects can improve performance. Using compressed references causes the Java objects, classes, threads, and monitors to be loaded into the LE HEAP31 storage area in 31-bit storage. If you have insufficient space in 31-bit storage, class loading fails, causing termination of the JVM. Setting the JVM command line option –Xnocompressedrefs disables the use of compressed references and instead loads the Java classes into 64-bit storage.

    2. JIT Compiler

      The JIT compiler is responsible for continuous optimization, by compiling Java byte code. Executable code is stored in the JIT code cache, and static data is stored in the JIT data cache. Prior to z/OS, Version 2 Release 3 and Java 8 SR5 the code cache is stored in 31-bit storage, whereas the data cache is stored in 64-bit storage. Depending on the number of Java applications, and the amount of JIT activity, the 31-bit JIT code cache can expand dynamically to a maximum size that is determined by the JVM setting -Xcodecachetotal. This defaults to 128 MB. If the cache becomes full, the JIT process stops but the JVM continues to operate with reduced potential performance. If you are using z/OS, Version 2 Release 3, you can free up more space in the 31-bit private area by upgrading to Java 8 SR5, which supports residency mode for 64-bit applications (RMODE64) for the JIT code cache. This stores the compiled JIT code in the 64-bit private area.

      6.3 Support for Java 8 and Java 11 is removed as of CICS® TS 6.3.

    3. UNIX shared libraries

      The shared library region is a z/OS feature that enables address spaces to improve the performance of the loading of UNIX System Services dynamic link library (DLL) files, and to share the associated real storage. The shared library function is disabled by default in CICS JVM servers, but is supported by the IBM Java SDK. When the first JVM process that uses shared libraries is started in the region, the shared library region reserves storage in the 31-bit high private area. For more information, see Tuning the z/OS shared library region.

      Note:

      As an approximate guideline if using Java 8 SR5 and a single application, the first JVM server to start within a CICS region can allocate anywhere between 51M to 115M of 31-bit private area depending on configuration and workload.

      The subsequent JVM servers have a lower footprint and can allocate anywhere between 8M and 73M, as the JVM DLL files need to only be loaded once.

      These figures do not include the UNIX shared library region, the value of which must also be added to the 31-bit storage if enabled.

  3. Calculate your 64-bit storage.

    Multiple JVM components can allocate storage from the 64-bit private area that includes the Java heap, native thread stack, Java classes, JIT compiler output, and Java monitors. The amount of 64-bit storage that is required can be estimated as a minimum of 2 GB, with additional storage required for larger workloads or more complex configurations.

    To more accurately estimate 64-bit storage, you need to consider:
    • The maximum Java heap value, set by using -Xmx.
    • The maximum number of all threads in the JVM. Each thread requires a minimum of 3 MB of Language Environment stack storage, including 1 MB of stack. This accounts for the minimum 1 MB native stack storage, 1 MB of reserve storage and the 1 MB Language Environment control block that is required to support each thread. See Identifying Language Environment storage needs for JVM servers.
    • Storage for the Java classes, JIT caches, and Language Environment 64-bit heaps. You can add a best guess of 300 MB - 500 MB depending on workload and configuration.
    Note: The Java shared class cache uses UNIX shared memory which does not count toward the CICS region's address space MEMLIMIT.

    The resulting figure needs to be rounded up to the next GB to account for the way that CICS GDSA expansion views guarded storage.

  4. Run the sample statistics program DFH0STAT to obtain storage statistics that are used to estimate z/OS storage.

    View the User region, extended user region and MEMLIMIT storage monitoring report for information about the state of unallocated storage in z/OS user region storage, extended user region storage and MEMLIMIT storage. The report also provides information about occurrences of short-on-storage (SOS) conditions in respective storage areas.

    View the Storage above 2 GB (64-bit storage) report for information about the use of 64-bit z/OS storage.

    • Note the values for  1  Current Unallocated Total, which indicate the current amount of unallocated storage in the z/OS user region storage (24-bit), the extended user region storage (31-bit), and MEMLIMIT storage (64-bit), respectively.
    • Note the value for  2  MEMLIMIT minus Current Address Space active, which indicates the current amount of 64-bit storage available to the CICS region.
    User region, extended user region and MEMLIMIT storage monitoring
    _________________________________________________________
                                                        User Region               Extended User Region                  MEMLIMIT
                                                       _________________________________________________________________________
      Last monitor sample time . . . . . . . . . . . :  03/11/20**  16:22:13      03/11/20**  16:22:13      03/11/20**  16:22:13
      State. . . . . . . . . . . . . . . . . . . . . :                Normal                    Normal  
      Current unallocated total. . . . . . . . . . . :                5,956K                  392,956K                     8162M   1 
      LWM unallocated total. . . . . . . . . . . . . :                5,956K                  392,956K                     8162M
      Current unallocated largest contiguous area. . :                5,956K                  392,168K                       N/A
      LWM unallocated largest contiguous area. . . . :                5,956K                  392,168K                       N/A
      Last date and time SOS . . . . . . . . . . . . :
      SOS duration...................................:         00:00:00.0000             00:00:00.0000             00:00:00.0000 
      Times SOS......................................:                     0                         0                         0      
      Current tasks waiting because SOS. . . . . . . :                     0                         0                       N/A 
      Peak tasks waiting because SOS . . . . . . . . :                     0                         0                       N/A
      Total waits because SOS. . . . . . . . . . . . :                     0                         0                       N/A
      Time tasks waited because SOS. . . . . . . . . :        00:00:00.00000            00:00:00.00000                       N/A  
    
    Storage ABOVE 2GB (64-bit storage)
    __________________________  
      MEMLIMIT Size. . . . . . . . . . . . :               15,360M 
      MEMLIMIT Set By. . . . . . . . . . . :                  JCL 
       
      Current Address Space active (bytes) :      1,164,967,936 
      Current Address Space active . . . . :             1,111M 
      Peak Address Space active. . . . . . :             1,375M  
      
      MEMLIMIT minus Current Address Space active. . . . . . . :          14,249M     2 
      Number of Private Memory Objects . . . . . . . . . . . . :               35 
        ....minus Current GDSA extents . . . . . . . . . . . . :               15 
      Bytes allocated to Private Memory Objects. . . . . . . . :           2,236M  =       2,344,615,936 
        ....minus Current GDSA allocated . . . . . . . . . . . :           1,212M  =       1,270,874,112
      Bytes hidden within Private Memory Objects . . . . . . . :           1,125M  =       1,179,648,000
        ....minus Current GDSA hidden. . . . . . . . . . . . . :           1,124M  =       1,178,599,424
          ....minus CICS Internal Trace Table hidden . . . . . :             130M 
      Bytes usable within Private Memory Objects . . . . . . . :           1,111M  =       1,164,967,936
      Peak bytes usable within Private Memory Objects  . . . . :           1,826M  =       1,914,699,776
      Current GDSA Allocated . . . . . . . . . . . . . . . . . :           1,024M  =       1,073,741,824
      Peak GDSA Allocated. . . . . . . . . . . . . . . . . . . :           1,024M 
    
  5. Start the JVM server and run a representative Java workload.
    Observe how the values change for each user region, and make sure that they are not constrained.

    During the initialization of the JVM server, checks on available 24-bit, 31-bit or 64-bit storage are performed. If the storage available at the time of the initialization is not enough, the initialization fails with message DFHSJ0914E.

What to do next

Set your Java memory limits based on the estimate you got. For instructions, see Setting the memory limits for Java.