Is it possible to get a server heap dump on a running process on linux (CentOS) using JMX from command line ?
can't open VisualVM, can't install jmap
It can be done with this simple code:
import com.sun.management.HotSpotDiagnosticMXBean;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.management.JMX;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
@SuppressWarnings("restriction")
public class CreateHeapDump
{
public static void main(String[] args) throws Exception
{
String host = args[0];
String port = args[1];
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi");
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
ObjectName mbeanName = new ObjectName("com.sun.management:type=HotSpotDiagnostic");
HotSpotDiagnosticMXBean bean = JMX.newMBeanProxy(mbsc, mbeanName, HotSpotDiagnosticMXBean.class, true);
String fileName = "heap_dump_" + new SimpleDateFormat("dd.MM.yyyy HH.mm").format(new Date()) + ".hprof";
boolean onlyLiveObjects = true;
bean.dumpHeap(fileName, onlyLiveObjects);
}
}
Compile it:
javac CreateHeapDump.java
Call it from command line:
java CreateHeapDump localhost 9010
This won't be pretty, but it works. Having said that, you might want to consider scripting this in Groovy or Jython, or even JavaScript.... I added a quickie add-on to jmxlocal, a project which implements standard JMX remoting for local JVMs. It now supports a command line invocation of one command against the connected MBeanServer, and the command must be specified in Java code.
Clone the repo and build with mvn clean install. Copy the jar (jmxlocal-1.0-SNAPSHOT.jar) to your target server. Execute the dump JMX command using the PID of the target java process as follows:
java -jar target/jmxlocal-1.0-SNAPSHOT.jar -j service:jmx:attach:///<PID> -c "conn.invoke(on(\"com.sun.management:type=HotSpotDiagnostic\"), \"dumpHeap\", new Object[]{\"/tmp/heap.dump\", true}, new String[]{String.class.getName(), boolean.class.getName()})"
The output will be
Command Executed. Result [null]
and you should find your dump file at /tmp/heap.dump.
If you need to, you can supply credentials using the -u [username] and -p [password] arguments.