Troubleshooting an MFT agent with a Java heap exhaustion error

While processing a number of managed transfer requests, such as file-to-file, message-to-file or file-to-message transfers, the agent abnormally ends (ABENDS) reporting a java.lang.OutOfMemoryError, and at the time your total RAM memory was not fully utilized. This exception has been caused by Java heap exhaustion.

About this task

When this issue occurs, the affected agent ABENDs and generates three files that provide details on the root cause:
  • An ABEND file. The name of this file conforms to the naming convention ABEND.FTE.date_timestamp.identifier.log.

    [UNIX, Linux, Windows, IBM i]On Multiplatforms, the file is written to the MQ_DATA_PATH/mqft/logs/coordination_qmgr_name/agents/agent_name/logs/ffdc directory.

    [z/OS]On z/OS®, the file is written to the z/OS UNIX System Services (z/OS UNIX) location $BFG_CONFIG/mqft/logs/coordination_qmgr_name/agents/agent_name/logs/ffdc

  • A Javacore file. The name of this file has the following format: javacore.datestamp.timestamp.pid.identifier.txt

    [UNIX, Linux, Windows, IBM i]On Multiplatforms, the file is written to the MQ_DATA_PATH/mqft/logs/coordination_qmgr_name/agents/agent_name directory.

    [z/OS]On z/OS, the file is written to the z/OS UNIX location $BFG_CONFIG/mqft/logs/coordination_qmgr_name/agents/agent_name directory.

  • A Java snap dump. The name of this file has the following format: snap.datestamp.timestamp.pid.identifier.txt

    [UNIX, Linux, Windows, IBM i]On Multiplatforms, the file is written to the MQ_DATA_PATH/mqft/logs/coordination_qmgr_name/agents/agent_name directory.

    [z/OS]On z/OS, the file is written to the z/OS UNIX location $BFG_CONFIG/mqft/logs/coordination_qmgr_name/agents/agent_name directory.

The ABEND and Javacore pair contain information similar to the examples shown below:

Abend file

Filename:   C:\ProgramData\IBM\MQ\mqft\logs\QM1\agents\AGENT1\logs\ffdc\ABEND.FTE.20220810102649225.189381242111774453.log
Level:      p920-005-220208
Time:       10/08/2022 10:26:49:225 BST
Thread:     45 (FileIOWorker-0:0)
Class:      com.ibm.wmqfte.thread.FTEThread
Instance:   a393304f
Method:     uncaughtException
Probe:      ABEND_001
Cause:      java.lang.OutOfMemoryError: Java heap space

java.lang.OutOfMemoryError: Java heap space
	at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:57)
	at java.nio.ByteBuffer.allocate(ByteBuffer.java:335)
	at com.ibm.wmqfte.util.impl.ByteBufferPoolImpl.getBuffer(ByteBufferPoolImpl.java:44)
	at com.ibm.wmqfte.transfer.frame.impl.TransferChunkImpl.getByteBuffer(TransferChunkImpl.java:181)
	at com.ibm.wmqfte.transfer.frame.impl.TransferChunkImpl.<init>(TransferChunkImpl.java:143)
	at com.ibm.wmqfte.transfer.frame.impl.TransferFrameSenderImpl.requestChunk(TransferFrameSenderImpl.java:636)
	at com.ibm.wmqfte.transfer.frame.impl.TransferFrameSenderImpl.access$000(TransferFrameSenderImpl.java:100)
	at com.ibm.wmqfte.transfer.frame.impl.TransferFrameSenderImpl$ChunkRequester.processFileIORequest(TransferFrameSenderImpl.java:142)
	at com.ibm.wmqfte.transfer.frame.impl.TransferFrameIOWorker.doWorkImpl(TransferFrameIOWorker.java:318)
	at com.ibm.wmqfte.io.impl.FTEFileIOWorker.doWork(FTEFileIOWorker.java:118)
	at com.ibm.wmqfte.io.impl.FTEFileIORequestQueue.run(FTEFileIORequestQueue.java:244)
	at java.lang.Thread.run(Thread.java:825)
	at com.ibm.wmqfte.thread.FTEThread.run(FTEThread.java:70) 
Javacore file

0SECTION       TITLE subcomponent dump routine
NULL           ===============================
1TICHARSET     437
1TISIGINFO     Dump Event "systhrow" (00040000) Detail "java/lang/OutOfMemoryError" "Java heap space" received
1TIDATETIMEUTC Date: 2022/08/10 at 09:26:53:917 (UTC)
1TIDATETIME    Date: 2022/08/10 at 10:26:53:917
1TITIMEZONE    Timezone: (unavailable)
1TINANOTIME    System nanotime: 350635184939400
1TIFILENAME    Javacore filename:    C:\ProgramData\IBM\MQ\mqft\logs\QM1\agents\AGENT1\javacore.20220810.102653.7172.0003.txt 

This issue occurs because of exhaustion of the Java heap memory for the JVM running the agent.

See How MFT agents use Java heap and native heap memory for more information on the distinctions between Java heap memory and native heap memory.

To help reduce the likelihood of this issue occurring, complete the following steps:

Procedure

  1. Increase the size of the Java heap for the JVM running the MFT agent.
    By default, the Java heap of an agent is set to 512 MB. Although this is satisfactory for small numbers of managed transfers, it might need to be increased to up to 1024MB (1GB) for production-like workload.
    Attention: When increasing the size of the Java heap for an agent, it is important to consider the other agents and applications that are running on the same system as these are using native heap. Increasing the size of the Java heap for an agent also increases its native heap usage, which in turn reduces the amount of native heap available to the other agents and applications. This means that there is an increased likelihood of agents and applications experiencing native heap exhaustion.
    • To increase or change the Java heap when running the agent as a normal process, set the BFG_JVM_PROPERTIES environment variable to pass the Java property -Xmx to the JVM.
      For example, on Windows, to set the maximum heap size to 1024 MB run the following command before using the fteStartAgent command:
      set BFG_JVM_PROPERTIES="-Xmx1024M"

      For more information about how to set Java system properties using the BFG_JVM_PROPERTIES environment variable, see Java system properties for MFT.

    • To increase or change the Java heap when running the agent as a Windows service, use the fteModifyAgent command and specify the -sj parameter to set the -Xmx property on the Windows service.
      The following example uses the fteModifyAgent command with the -sj parameter, to set the maximum size of the Java heap for a JVM running a Windows service configured agent to 1GB (1024MB):
      fteModifyAgent.cmd -agentName AGENT1 -s -su user1 -sp passw0rd -sj -Xmx1024M
      You can check this has been successfully set, by reviewing the output0.log file of the agent, after the agent has been restarted. In the Start Display Current Environment section, a value of 1024 MB will be reported, as follows:
      The maximum amount of memory that the Java virtual machine will attempt to use is: '1024'MB
  2. Restrict Java heap usage by reducing the workload of the agent.

    Typically, java.lang.OutOfMemoryErrors caused by Java heap exhaustion are the result of an agent doing too much work. Every managed transfer and managed call that an agent is processing uses memory in the Java heap, as do managed transfers and managed calls that are on the backlog of an agent. Resource monitors also use Java heap memory when they perform a poll.

    This means that as the workload of an agent increases, the amount of Java heap that it is using also grows as well.

    Reducing the workload of the agent can help here. To do this:
    • Set the following agent properties to a lower value:
      • maxQueuedTransfers
      • maxSourceTransfers
      • maxDestinationTransfers
    • Move some of the resource monitors of the agent to a new agent.

    This reduces the number of concurrent transfers that can occur, and therefore decreases the maximum concurrent workload for the agent.

  3. Enable memory allocation checking.

    The memory allocation checking functionality ensures that agents only start to process a new managed transfer if there is enough Java heap memory for it to run to completion. If there is insufficient memory, the managed transfer is rejected.

    This functionality is off by default. To enable it for an agent:
    • Add the following entry to the agent.properties file of the agent:
      enableMemoryAllocationChecking=true
    • Restart the agent
    Note: The memory allocation checking functionality uses the maximum amount of memory that a managed transfer requires, which might be more than the actual amount of memory used (particularly for message-to-file and file-to-message transfers). This means that turning it on can result in fewer managed transfers being processed by an agent.
  4. If the agent continues to experience java.lang.OutOfMemoryErrors due to Java heap exhaustion, then run the fteRas command to collect the ABEND files, Javacores, heap dump files and snap dump files (along with other useful information about the MFT topology), and make the output available to IBM® Support for analysis.