Managing your JVM pool for performance

Java™ Applications in CICS® explains how the JVM pool is structured, and what CICS does to manage the JVMs in it.

As that topic explains, the number of JVMs that a single CICS Transaction Server for z/OS® region can support is governed mainly by:

To estimate how many JVMs you need to support a desired level of transaction throughput, use the formula:

ETR x Response time = Number of JVMs

where
ETR is the desired level of transaction throughput
Response time is the time taken to run your transaction in a JVM

By following the tuning processes described in this topic, you might be able to:

As described in Tuning storage for individual JVMs and Tuning Language Environment enclave storage for JVMs, you can tune the storage settings and Language Environment® enclave settings for your JVMs to adjust the amount of storage that is used by a single JVM. In addition to this, you can ensure that your CICS region is set up so that the JVM pool contains the optimum number of JVMs for the MVS storage space and processor time that are available to the region, and so that processor time is not being wasted on unnecessary activities. A suggested process for tuning your JVM pool is as follows:

  1. Examine the amount of CPU time that is used by your JVMs on their own J8 and J9 TCBs. Check that you have chosen the optimum level of reusability for each of your JVMs, considering the design of the applications that use them. Make sure that you have stopped any unnecessary CPU usage caused by the use of tracing, by the use of the USEROUTPUTCLASS option in JVM profiles, or by resettable JVMs that are being re-initialized instead of being reset. You might also be able to reduce the initialization time for your JVMs. Then decide if you want to increase or reduce the number of JVMs in the CICS region, considering the time that transactions are having to wait to acquire a JVM. Take into account your level of QR TCB utilization, because a high level can mean that adding more JVMs might not increase the throughput of your system. Examining the CPU time used by your JVMs tells you how to do this.
  2. If you find that you want to increase the number of JVMs, compare the amount of storage needed to support a single JVM, with the amount of storage space that is available (or that you could make available) to the CICS region, and calculate the maximum number of JVMs that your CICS region could support. Calculating the maximum number of JVMs for which storage can be provided tells you how to do this.
  3. Taking your findings about CPU usage and storage availability into account, choose and set an appropriate MAXJVMTCBS limit for the CICS region. Choosing and setting an appropriate MAXJVMTCBS limit tells you how to do this.
  4. If you subsequently receive warnings about MVS storage constraints, re-examine the storage settings for your JVMs, and adjust the storage settings, the MAXJVMTCBS limit, or both, to decrease the amount of storage that the JVMs in the CICS region are using. Dealing with warnings about MVS storage constraints tells you how to do this.
  5. If you find that the incidence of mismatching and stealing in your JVM pool is excessive, and JVMs are frequently being destroyed and re-initialized to fulfil requests for a JVM with a different profile, you can indirectly limit the number of JVMs with a particular profile by limiting the number of transactions that request a JVM with that profile. Dealing with excessive mismatches and steals tells you how to do this.

Examining the CPU time used by your JVMs

To find out if the performance of your CICS region could benefit from an increase or a reduction in the number of JVMs, you can use CICS monitoring and statistics information to help you answer the following questions:

  1. Have I chosen the optimum level of reusability for each of my JVMs, considering the design of the applications that use them?
  2. Have I stopped any unnecessary CPU usage by my JVMs?
  3. How long are transactions having to wait to acquire a JVM?
  4. Is the level of QR TCB utilization a limiting factor for this CICS region?

Here's how to do this:

1. Have I chosen the optimum level of reusability for each of my JVMs?

"How JVMs are reused and reset" in Java Applications in CICS explains the three levels of reusability for JVMs: resettable JVMs, continuous JVMs, and single-use JVMs. Before changing the level of reusability for a JVM, read that topic.

The level of reusability for a JVM is determined by the REUSE option in the JVM profile. Although some levels of reusability give a higher performance than other levels of reusability, there are important programming considerations for Java applications in each case. The performance characteristics and programming considerations for each level of reusability can be summarized as follows:

Table 14. Reuse and reset characteristics of JVM types
JVM type (and action between JVM uses) REUSE option in profile Compatible with the shared class cache? Are program invocations allowed to pass state to subsequent invocations? Are programs allowed to change characteristics of the JVM? Performance
Resettable (JVM reused and reset) REUSE= RESET Yes No (JVM storage cleaned up after each use) No (JVM destroyed if this occurs) Medium (JVM reset, but not initialized for each use)
Continuous (JVM reused but not reset) REUSE= YES Yes Yes Yes Highest (JVM not initialized or reset for each use)
Single-use (JVM destroyed) REUSE= NO No No (JVM destroyed) Yes Lowest (JVM initialized for each use)

The performance of resettable and continuous JVMs is also influenced by whether or not they use the shared class cache: that is, whether they are worker JVMs with the option CLASSCACHE=YES in their JVM profiles, as opposed to standalone JVMs with the option CLASSCACHE=NO in their JVM profiles. The master JVM in a CICS region must be either resettable or continuous, and all the worker JVMs inherit their level of reusability from the master JVM. "How JVMs are reused and reset" in Java Applications in CICS has more information about the relationship between the shared class cache and the level of reusability.

Worker JVMs have a shorter initialization time than standalone JVMs. Broadly speaking, the JVM's relationship to the shared class cache makes the greatest difference to its initialization time, but the level of reusability makes the greatest difference to a JVM's performance in terms of overall transaction processor time.

In terms of initialization time, the performance of the different types of JVM can be ranked as follows:

[Shortest]
Resettable worker JVM
Continuous worker JVM

Resettable standalone JVM
Single-use JVM [but see note below]
Continuous standalone JVM
[Longest]

It is important to note that although the initialization time for a single-use JVM is about the same as for a resettable standalone JVM, this initialization time occurs every time a program runs in this type of JVM, making the cumulative initialization time much longer. You should also bear in mind that the first JVM that is initialized in a CICS region, whatever its type, has a longer initialization time than subsequent JVMs initialized in the region, because of the setup required at this time.

In terms of the processor time used for each transaction, the performance of the different types of JVM can be ranked as follows:

[Shortest]
Continuous JVM (standalone or worker)
Resettable JVM (standalone or worker)


Single-use JVM [because of initialization for each use]
[Longest]

Some applications perform slightly better in a worker JVM, and some applications perform slightly better in a standalone JVM.

The level of reusability for a JVM must be matched to the applications that run in it. To ensure that all your JVMs are operating at the optimum level of reusability for the applications that run in them, you can use these guidelines for selecting a REUSE setting in the JVM profile:

Resettable JVMs (REUSE=RESET)
This level of reusability gives medium performance, because although the JVM is initialized only once (not for each use, as the single-use JVM is), a JVM reset is performed each time a Java program finishes running in the JVM. However, the reset provides protection for programs against the potential actions of a previous program invocation in the same JVM. Once the JVM has been reset, the application code that runs for the next Java program is unable to determine whether it is running in a new JVM or a JVM that has been reset. Resettable JVMs can also use the shared class cache to reduce their storage requirements and their initialization time, if the master JVM for the CICS region is resettable (with the option REUSE=RESET in its JVM profile). If an application is using a resettable JVM, you need to make sure that the Java programs are not performing unresettable actions, because this causes the JVM to be destroyed instead of being reset, which greatly reduces the performance of the JVM. "How JVMs are reused and reset" in Java Applications in CICS explains how to do this.
Continuous JVMs (REUSE=YES)
This level of reusability gives the highest performance of the three levels, because the JVM is initialized only once, not for each use, and no JVM reset is performed between each use. However, the absence of a reset means that the application code that runs in the next Java program or transaction might be affected by the actions of the previous program invocation. The applications that use this type of JVM must be designed and tested to ensure that they can run in a continuous JVM without causing any undesirable consequences for subsequent program invocations in the same JVM, following the guidelines in "How JVMs are reused and reset" in Java Applications in CICS. Continuous JVMs can also use the shared class cache to reduce their storage requirements and their initialization time, if the master JVM for the CICS region is continuous (with the option REUSE=YES in its JVM profile).
Single-use JVMs (REUSE=NO)
This level of reusability gives the lowest performance of the three levels, because a new JVM is initialized for each program invocation, and destroyed after use. This means programs cannot affect subsequent program invocations, but the initialization of a new JVM for each program incurs very high CPU costs. Single-use JVMs are also not permitted to use the shared class cache. New Java applications should not be developed in such a way that they can only run in a single-use JVM. You should only use this type of JVM for Java programs that must perform an unresettable action, and cannot at present be re-designed to eliminate this action so that they could run in a resettable JVM or in a continuous JVM. To improve performance, you should re-design these programs as soon as you can.

Selecting the optimum level of reusability for each of your JVMs ensures that you are not wasting CPU time by performing JVM re-initializations, or JVM resets, in situations where these actions are not required for the correct operation of the applications that use the JVM.

2. Have I stopped any unnecessary CPU usage by my JVMs?

The CICS monitoring facility can be used to monitor the CPU time used by a transaction that invokes a JVM program, including the amount of CPU time used by the JVM on a J8 or J9 TCB. The CICS monitoring facility also includes the elapsed time spent in the JVM, and the number of JCICS API requests issued by the JVM program. The relevant monitoring data fields, most of which are in performance data group DFHTASK, are shown in Table 15.

Table 15. JVM-related monitoring data fields
Group Field ID Field name Description
DFHTASK 253 JVMTIME The total elapsed time spent in the JVM by the user task. This comprises the JVM initialization time, the Java application execution time, and the JVM reset time. The fields JVMITIME and JVMRTIME show the initialization and reset time respectively.
DFHTASK 254 JVMSUSP The elapsed time the user task was suspended by the CICS dispatcher while running in the JVM.
DFHTASK 260 J8CPUT The processor time during which the user task was dispatched by the CICS dispatcher domain on a CICS J8 mode TCB (used for JVMs in CICS key). The field JVMTIME shows the actual elapsed time spent in the JVM.
DFHTASK 267 J9CPUT The processor time during which the user task was dispatched by the CICS dispatcher domain on a CICS J9 mode TCB (used for JVMs in user key). The field JVMTIME shows the actual elapsed time spent in the JVM.
DFHTASK 273 JVMITIME The elapsed time spent initializing the JVM environment.
DFHTASK 275 JVMRTIME The elapsed time spent resetting the JVM environment to its initial state. This includes any garbage collection that takes place in the JVM.
DFHTASK 277 MAXJTDLY The elapsed time in which the user task waited to obtain a CICS JVM TCB (J8 or J9 mode), because the CICS system had reached the limit set by the system parameter, MAXJVMTCBS.
DFHCICS 025 CFCAPICT The number of CICS OO foundation class requests, including the Java API for CICS (JCICS) classes, issued by the user task.

When looking at JVM initialization time, bear in mind that the first JVM that is initialized in a CICS region, whatever its type, has a longer initialization time than subsequent JVMs initialized in the region, because of the setup required at this time. Depending on your applications, specifying the Xservice="-Xquickstart" option in your JVM profiles can provide some reduction in the initialization time for your JVMs. The option causes the just-in-time (JIT) compiler function of the JVM to omit certain optimizations when a method is first compiled. If the method is used frequently enough, the JIT compiler compiles it again using all the optimizations. This technique improves initialization time for the JVM, but performance can be degraded on subsequent reuses of the JVM, because the code is not fully optimized or because of the time required for the second compile.

When looking at JVM reset time, note that for a continuous JVM (with the option REUSE=YES in its JVM profile), the JVM reset time is usually zero, but not always. This is because although continuous JVMs are not reset after each use, CICS still requests garbage collection for these JVMs every 101 transactions. This process takes place after the 101st use of the JVM, and garbage collection is recorded as JVM reset time.

Even if you do not plan to change the number of JVMs in your CICS region, you should ensure that the JVMs are not using unnecessary CPU time. In particular, look out for the following issues:

Tracing

Setting the CICS master system trace flag on significantly increases the CPU cost of a JVM program execution. In a production environment, consider running your CICS region with this flag set off. You can do this by initialising CICS with SYSTR=OFF, or by using the CETR transaction.

Activating tracing for JVMs also increases the CPU cost. JVM tracing can produce large amounts of output in a very short time. Ensure that you normally only activate JVM trace for special transactions. Java Applications in CICS tells you how to control JVM tracing.

The USEROUTPUTCLASS option

Specifying the USEROUTPUTCLASS option in a JVM profile has a negative effect on the performance of JVMs. The USEROUTPUTCLASS option enables developers using the same CICS region to separate out their own JVM output, and direct it to an identifiable destination of their choice, but it involves the building and invocation of additional class instances. For best performance in a production environment, you should not use this option; reserve it for use during application development.

The CICS-supplied JVM profiles do not specify the USEROUTPUTCLASS option.

Unresettable events in resettable JVMs

In some circumstances, you might find that some of the resettable JVMs in your CICS region are not actually being successfully reset, but instead are being discarded and re-initialized for each transaction, at a higher CPU cost. This happens because one or more unresettable events has taken place in the JVM. The most frequent cause of an unresettable event is that the Java program that just ran in the JVM has performed an unresettable action. An unresettable action is when a program uses Java interfaces that modify the state of a JVM in a way that cannot be properly reset, such as changing system properties or loading a native library. The document Persistent Reusable Java Virtual Machine User's Guide, SC34-6201, has more information about these unresettable actions. If one or more such actions are detected during the execution of a user's Java program, the JVM is marked unresettable, and CICS destroys the JVM when the Java program has finished using it. The storage used by the JVM is recovered, and a new JVM is initialized. Unresettable events can also occur if there is an error in the JVM code.

In the CICS statistics for JVM profiles (see JVM profile statistics), the field "Number of times JVMs were unresettable for this profile" shows the number of unresettable JVMs for each JVM profile and execution key. If the statistics show that there were unresettable JVMs for a JVM profile that specifies the option REUSE=RESET or the older option Xresettable=YES, meaning that the JVMs should have been resettable, then it is probable that some of the applications requesting that JVM profile are performing unresettable actions. You can identify those applications by looking at byte 6, bit 0 of the transaction flags field, TRANFLAG (field 164 in group DFHTASK), in the CICS performance class monitoring record for each transaction, which indicates if a JVM was not reset. The JVM monitors the use of interfaces that prevent resetting, and the events that prevent reuse are logged (provided that the appropriate event logging system properties are specified in the JVM properties file for the JVM).

"How JVMs are reused and reset" in Java Applications in CICS explains more about the levels of reusability for JVMs and the process of resetting a JVM, and tells you how to log unresettable actions during testing of your Java programs. Your Java programs should not perform unresettable actions when they are used in a production environment. If you can eliminate these actions, the performance of your resettable JVMs should improve significantly.

3. How long are transactions having to wait to acquire a JVM?

To find out how long your transactions are having to wait to acquire a JVM, look at the delay time for the JVM pool, shown in the statistics field "Total Max TCB Pool Limit delay time" in the CICS dispatcher TCB pool statistics (see Dispatcher domain: TCB Pool statistics). This tells you how long your transactions waited to acquire a JVM at those times when the MAXJVMTCBS limit had been reached for the JVM pool.

You can use the CICS monitoring data field MAXJTDLY (field ID 277), in performance data group DFHTASK, to check the time that an individual transaction was made to wait to acquire a JVM.

4. Is the level of QR TCB utilization a limiting factor for this CICS region?

If you have found that the delay time for transactions waiting to acquire a JVM is excessive, you still need to check your level of QR TCB utilization before deciding to increase your MAXJVMTCBS limit. Calls made by a Java program for CICS services, such as using a JCICS class to access VSAM data, require a switch to the QR TCB. (The monitoring data field CFCAPICT, in group DFHCICS, shows how many such calls each transaction makes.) Once the QR TCB has reached a high level of utilization, then adding more JVMs (on J8 and J9 TCBs) might produce no further increase in the throughput of your CICS system. You can check your level of QR TCB utilization by looking at the statistics field "Accum CPU Time / TCB" for the QR mode in the CICS dispatcher TCB mode statistics (see Dispatcher domain: TCB Mode statistics).

Calculating the maximum number of JVMs for which storage can be provided

If you have decided that your CICS region could benefit from an increase in the number of JVMs, you now need to work out the maximum number of JVMs that your CICS region could support. This maximum number can be calculated as:

free storage available in the CICS address space / storage needed per JVM

To determine the amount of free storage available in the CICS address space, you can use the CICS-supplied sample statistics program DFH0STAT. The Storage Reports (see Storage Reports) include the amount of user storage allocated above and below the 16MB line. The same information can also be obtained from the job termination message IEF374I. 'VIRT=nnnnnK' shows you the virtual storage below 16MB, and 'EXT=nnnnnnnK ' shows you the virtual storage above 16MB.

When you begin to use JVMs in the CICS region, two amounts of storage are allocated:

  1. The storage that is reserved for the z/OS shared library region. This storage is allocated in each CICS region when the first JVM is started in the region. (This might be the master JVM that initializes the shared class cache.) The amount of storage is controlled by the SHRLIBRGNSIZE parameter in MVS. Tuning the z/OS shared library region tells you how to adjust this amount of storage, if necessary.
  2. The MVS storage cushion that CICS allocates to provide a buffer for storage requests by JVMs. The storage cushion is pre-set by CICS at 20MB. This storage is allocated in each CICS region when the first worker or standalone JVM (not the master JVM) is started in the region.

If you measured the free storage available in a CICS address space when no JVMs were present, you should subtract these amounts of storage from the total amount of free storage available in the CICS address space.

If your CICS region includes a shared class cache, you also need to subtract the storage required for the shared class cache facility, from the total amount of free storage available in the CICS address space. Although there is only one active shared class cache in a CICS region at any one time, the region might also need to contain a new shared class cache that is being loaded to replace the existing shared class cache, or old shared class caches that are still present in the region because they are waiting for worker JVMs that are dependent on them to be phased out. Each shared class cache, whether new, current or old, has its own master JVM.

The activities that cause new or old shared class caches to be present in your CICS region as well as the current shared class cache are:

These activities are performed manually at your command, rather than being performed automatically by CICS. In a production system that has been correctly tuned, these activities are not likely to occur often, so it is not likely that the CICS region would need to contain more than one new or old shared class cache in addition to the current shared class cache. In these circumstances, you could allow sufficient storage for two shared class caches and their master JVMs, subtracting this from the total amount of free storage available in the address space. In a CICS region that is being heavily used for development and testing, you might want to allow sufficient storage for three shared class caches and their master JVMs, in case changes must be made to the current shared class cache before all the worker JVMs using an old shared class cache have been phased out.

The total amount of storage required for a shared class cache and its master JVM can be calculated by adding together:

  1. The size of the shared class cache. This is specified by the JVMCCSIZE system initialization parameter, but it can be changed by various commands while CICS is running, and the changed size can be kept across CICS restarts. Issue the CEMT INQUIRE CLASSCACHE command to check the current size that is specified for the shared class cache.
  2. The amount of storage specified by the Xmx option in the JVM profile for the master JVM. Xmx specifies the maximum total size for the transient and middleware heaps, and because the master JVM is not used to run applications, these heaps can be small. The value of Xmx in the CICS-supplied sample profile for a master JVM, DFHJVMCC, is 4MB.
  3. The basic JVM cost for a master JVM, which is 9MB.

For example, if you use the default value of 24MB for the JVMCCSIZE system initialization parameter, and you use the default CICS-supplied sample profile DFHJVMCC as the profile for your master JVM, the storage required for a shared class cache and a master JVM in your CICS region is 24MB + 4MB + 9MB = 37MB. In a production system, this result would mean you should subtract 74MB of storage (enough for two shared class caches and their master JVMs) from the free storage available in the CICS address space, before calculating the number of JVMs that the CICS region can support.

You can calculate the amount of storage needed per JVM from the storage heap settings in your JVM profiles. Below the 16MB line, each additional JVM that is started (regardless of its type) uses approximately 12KB of storage. Above the 16MB line, the amount of storage used for a JVM can be calculated by adding the amount of storage specified by the Xmx option in the JVM profile (which specifies the maximum total size for the transient and middleware heaps) to the basic storage cost for the type of JVM, as follows:

If your CICS region contains JVMs that all use the same JVM profile, or specify the same amount of storage for the Xmx option in their JVM profiles, the calculation is straightforward. For example, if the JVMs in your CICS region are worker JVMs using the same JVM profile, the maximum number of JVMs that your CICS region can support is the lower of:

Available Virtual Storage < 16MB / 12k
or
Available Virtual Storage > 16MB / (10MB + Xmx for worker JVM)

However, as described in Tuning storage for individual JVMs, your applications might use several JVM profiles that specify different storage heap sizes. In this case, to work out a better estimate of the number of JVMs that your CICS region can support, you should take into account the proportions of each type of JVM that would typically be in the JVM pool for your CICS region. When you collect CICS statistics for JVM profiles (see JVM profile statistics), you can see the Xmx option for each of the JVM profiles in use in your CICS region, and the level of activity for each of those JVM profiles. You can use this information to calculate the approximate amount of storage needed for an ‘average’ JVM in your CICS region, based on the storage requirements of each type of JVM and their relative levels of usage. A suggested method is as follows:

  1. Use the sum basic JVM cost for JVM type + Xmx to calculate the amount of storage needed for a JVM with each of the JVM profiles that are in use in your CICS region, using the information in the field "-Xmx value for this profile".
  2. The field "Total number of requests for this profile" tells you how many times each type of JVM was requested by an application during your sampling period, and this should reflect the proportions of each type of JVM that would typically be in the JVM pool. Multiply the total number of requests for each JVM profile, by the storage requirement you have calculated for that profile.
  3. Add together the results of Step 2 for all the JVM profiles, and then divide this figure by the total number of requests for JVMs in the sampling period.

For example, take the case where:

Your final calculation would be:

(Prof A requests * Prof A storage) + (Prof B requests * Prof B storage)
  / Total JVM requests
which gives:
(300 * 54) + (200 * 70) / 500 = 60.4
The ‘average’ JVM in this CICS region needs approximately 60.4MB of storage.

You can divide the available virtual storage above the 16MB line in your CICS region, by this ‘average’ JVM's storage requirement, to make an approximate calculation of the maximum number of JVMs that your CICS region can support. This estimate is based on the assumption that the use of each JVM profile by your applications will remain similar to what it was during the sampling period, and so the JVM pool will have a similar composition.

Choosing and setting an appropriate MAXJVMTCBS limit

Taking your findings about CPU usage and storage availability into account, you can now choose and set an appropriate MAXJVMTCBS limit for the CICS region.

As explained in Java Applications in CICS, the MAXJVMTCBS system initialization parameter limits the total number of TCBs in the pool of J8- and J9-mode open TCBs that CICS uses for JVMs. Each JVM executes on a J8 or J9 TCB, so MAXJVMTCBS limits the number of JVMs that can be active in the CICS region. The JM TCB, for the master JVM that initializes the shared class cache, does not count towards the MAXJVMTCBS limit.

MAXJVMTCBS can be in the range 1 through 999. The default setting is 5. The minimum permitted value is 1, meaning that CICS is always able to create at least 1 open TCB (in J8 or J9 mode) for use by a JVM.

The CICS System Definition Guide tells you how to specify the MAXJVMTCBS system initialization parameter. You can also change the setting for MAXJVMTCBS without restarting CICS, by using the CEMT SET DISPATCHER MAXJVMTCBS command (see CICS Supplied Transactions).

Dealing with warnings about MVS storage constraints

If you set a MAXJVMTCBS limit that is too high, CICS might attempt to create too many JVMs for the available MVS storage, resulting in an MVS storage constraint.

CICS has a storage monitor for MVS storage, which notifies it when MVS storage is constrained or severely constrained, so that it can take short-term action to reduce the number of JVMs in the JVM pool. (The storage monitor uses exits in Language Environment routines; it is not a monitoring transaction.) As JVMs make requests for MVS storage, the storage monitor checks whether the availability of MVS storage has dropped below a pre-set threshold of 40MB, and notifies CICS when this is the case. At this point, operator message DFHSM0137 informs you that MVS storage is constrained. The storage monitor also notifies CICS if the availability of MVS storage has become so low that MVS storage requests can only be satisfied from a pre-set MVS storage cushion of 20MB. At this point, operator message DFHSM0139 informs you that MVS storage is severely constrained (a short-on-storage situation). CICS also produces statistics for time spent in waits because of MVS storage constraints (in the Storage Above 16MB report).

Once CICS has been notified that MVS storage is constrained or severely constrained, the actions it takes, depending on the seriousness of the situation, are as follows:

When CICS manages to reduce its use of MVS storage by these methods, and the availability of MVS storage has risen above the pre-set MVS storage cushion or the pre-set threshold, the storage monitor informs CICS that it can return to normal operation. As CICS returns to normal operation, operator messages DFHSM0138 or DFHSM0140 inform you when MVS storage is no longer constrained or severely constrained.

When you receive operator messages relating to an MVS storage constraint, or see in statistics reports that time has been spent in waits caused by MVS storage constraints, you should examine why the MVS storage constraint occurred, and take steps to prevent a recurrence. The likely cause of the MVS storage constraint is that the MAXJVMTCBS limit for your CICS region is set at too high a level, considering the amount of storage that is needed by your JVMs, and the amount of MVS storage that you have available. In this situation, you should:

Dealing with excessive mismatches and steals

"How CICS allocates JVMs to applications" in Java Applications in CICS explains how CICS assigns JVMs to applications, and tries to avoid mismatches and steals wherever it makes sense to do so.

To summarize, when an application requests a JVM, CICS first tries to find a suitable JVM that is available for reuse in the JVM pool. If a suitable JVM, with the correct JVM profile and execution key, is not available, and the MAXJVMTCBS limit for the JVM pool has not yet been reached, CICS can create a new JVM for the application.

If there are no suitable JVMs and no space in the JVM pool, CICS can fulfil an application’s request for a JVM by destroying and re-initializing an available JVM that had the wrong execution key or profile for the request. This is called a mismatch if the JVM is destroyed and re-initialized but the TCB is kept and re-used, and a steal if both the JVM and the TCB are destroyed and replaced (because the TCB has been "stolen" from one TCB mode (J8 or J9) by another TCB mode). Before allowing a mismatch or a steal, CICS uses its selection mechanism to decide whether it is worthwhile, or whether it is more economical to make the application wait until a suitable JVM is available, and to keep the free JVM for a request that can benefit more from it.

The selection mechanism is designed to avoid excessive mismatches and steals, while ensuring that no application waits too long to receive a JVM. CICS should normally be able to maintain an appropriate balance between the different types of JVM in the JVM pool, without operator intervention. However, you might occasionally want to limit the numbers of a certain type of JVM, if you are not satisfied with the measures CICS is taking to avoid mismatches and steals for that type of JVM. For example, take the case where a certain transaction specifies a JVM profile that is not used by other transactions. If the transaction is relatively unimportant, you might prefer to have only one JVM of that type in the JVM pool to service those requests, and make further requests queue if that JVM is not available. However, you might find that the requests are waiting longer than the critical period that is defined by CICS, and so CICS is giving the requests free JVMs with the wrong profile or execution key, and causing a mismatch or a steal.

You can use the CICS statistics to see if the incidence of mismatches and steals in the JVM pool is greater than you would like. In the CICS dispatcher TCB mode statistics (see Dispatcher domain: TCB Mode statistics), the statistics fields "TCB Mismatches" and "TCB Steals", for the TCB modes J8 and J9, show the overall incidence of mismatches and steals in the JVM pool. In the CICS statistics for JVM profiles (see JVM profile statistics), the field "Number of times this profile stole a TCB" shows the combined incidence of both mismatches and steals for each JVM profile.

You cannot specify the number of JVMs with each JVM profile that CICS keeps in the JVM pool. However, you can indirectly limit the number of JVMs with a particular JVM profile, by limiting the number of transactions that request a JVM with that profile. To do this, define the transactions which execute JVM programs requiring that JVM profile, in the same transaction class (TRANCLASS). Assign a MAXACTIVE value to the TRANCLASS. This limits the number of concurrent executions of JVM programs requiring that JVM profile, and so limits the maximum number of JVMs with that JVM profile that will be in the JVM pool at any one time.

As an alternative, you could attempt to reduce the number of different JVM profiles that are used by your CICS region. The fewer the number of JVM types you have, the more chance there is of an existing JVM matching an application's request, and so the incidence of mismatches and steals should be reduced. Check that all your JVM profiles and their associated JVM properties files do actually specify different options, and investigate whether you could combine compatible options in different JVM profiles to create a single JVM profile. For example, if you found two infrequently-used JVM profiles that contained similar options, but one specified a larger storage heap size, you could consider combining these into a single JVM profile that specified the larger storage heap size. This would mean that some applications would be using an unnecessarily large JVM, but the reduction in the incidence of mismatches and steals might make this worthwhile. "Setting up JVM profiles and JVM properties files" in Java Applications in CICS tells you how to work with JVM profiles and JVM properties files.

Related concepts
How CICS manages JVMs in the JVM pool
How CICS allocates JVMs to applications
How JVMs can be reset for reuse

Related tasks
Java applications using a Java virtual machine (JVM): improving performance
Tuning storage for individual JVMs
Tuning Language Environment enclave storage for JVMs
Tuning the z/OS shared library region
Tuning for enterprise beans
Setting up JVM profiles and JVM properties files
Managing your JVMs
Specifying CICS system initialization parameters
Controlling tracing for JVMs

Related reference
CEMT SET DISPATCHER
Performance data in group DFHTASK
Dispatcher domain: TCB Mode statistics
Dispatcher domain: TCB Pool statistics
JVM Pool statistics
JVM profile statistics
JVM program statistics
[[ Contents Previous Page | Next Page Index ]]