在Linux(CentOS)上,是否可以使用JMX从命令行获取正在运行的进程的服务器堆转储?
无法打开VisualVM, 无法安装jmap。
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);
}
}
编译它:
javac CreateHeapDump.java
从命令行调用它:
java CreateHeapDump localhost 9010
这不会很漂亮,但它能工作。话虽如此,您可能想考虑使用Groovy或Jython甚至JavaScript来编写脚本....
我向jmxlocal添加了一个快速附加组件,该项目实现了本地JVM的标准JMX远程控制。它现在支持针对连接的MBeanServer执行一个命令的命令行调用,并且必须在Java代码中指定该命令。
克隆存储库并使用mvn clean install进行构建。 将jar文件(jmxlocal-1.0-SNAPSHOT.jar)复制到目标服务器。 使用目标Java进程的PID执行转储JMX命令,如下所示:
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()})"
输出结果将会是:
Command Executed. Result [null]
你应该在/tmp/heap.dump找到你的转储文件。
如果需要,你可以使用-u [用户名]和-p [密码]参数提供凭据。