Java heapdumps and core files can be useful in diagnosing a wide range of problems, from memory leaks to unexpected hangs. In most cases the JVM should produce a core file and a heap dump automatically if an OutOfMemoryError is thrown or if the JVM receives a SIGQUIT signal, for example from issuing a kill -3 against the DataFlowEngine process.

However in some cases the signal is not correctly processed by the JVM in which case some alternative means of generating a heap dump or javacore file is required. In cases like these, one trick we often use in service is to deploy a simple flow which calls a JCN with the code to take the heap dump.

In the example below I have used a HTTPInput Node set to read from the URI /heapDump to drive a very simple flow consisting of a HTTP Input Node, a Java Compute Node and a HTTP Reply Node:

The code for the Java compute node is given below, most of this is from the default template but I have highlighted the 2 lines that I have added:

import com.ibm.broker.javacompute.MbJavaComputeNode;
import com.ibm.broker.plugin.MbException;
import com.ibm.broker.plugin.MbMessage;
import com.ibm.broker.plugin.MbMessageAssembly;
import com.ibm.broker.plugin.MbOutputTerminal;
import com.ibm.broker.plugin.MbUserException;
import com.ibm.jvm.Dump;

public class HeapDumpFlow_JavaCompute extends MbJavaComputeNode {

public void evaluate(MbMessageAssembly inAssembly) throws MbException {
MbOutputTerminal out = getOutputTerminal(“out”);
MbOutputTerminal alt = getOutputTerminal(“alternate“);

MbMessage inMessage = inAssembly.getMessage();
MbMessageAssembly outAssembly = null;
try {
// create new message as a copy of the input
MbMessage outMessage = new MbMessage(inMessage);
outAssembly = new MbMessageAssembly(inAssembly, outMessage);
// —-—-—-—-—-—-—-—-—-—-—-—-—-—-
// Add user code below
Dump.HeapDump();
// End of user code
// —-—-—-—-—-—-—-—-—-—-—-—-—-—-
} catch (MbException e) {
// Re-throw to allow Broker handling of MbException
throw e;
} catch (RuntimeException e) {
// Re-throw to allow Broker handling of RuntimeException
throw e;
} catch (Exception e) {
// Consider replacing Exception with type(s) thrown by user code
// Example handling ensures all exceptions are re-thrown to be handled in the flow
throw new MbUserException(this, “evaluate()”, “”, “”, e.toString(),
null);
}
// The following should only be changed
// if not propagating message to the ‘out’ terminal
out.propagate(outAssembly);

}

}

Once the flow has been deployed, I can use a simple http client like curl or even a web browser to invoke the flow and generate a heap dump.

Ffor example:

curl http://localhost:7080/heapDump

As well as the HeapDump() method, there are a number of other facilities available from the com.ibm.jvm.Dump class which are documented in the Javadoc for this class.

Note: The com.ibm.jvm.Dump class is only available on platforms with an IBM JVM.

Remember that taking JVM dumps is an invasive procedure. You should remove the flow from your Broker once you have finished collecting heapdumps to avoid the possibility of unintentionally triggering core dumps in the future, especially on performance critical production machines.

 

Join The Discussion

Your email address will not be published. Required fields are marked *