如何在 Java 应用程序中创建堆转储?

How to create a heap dump inside a Java app?

我想创建一个 Java 堆转储分析器项目用于教育目的。我更喜欢在我的应用程序中捕获转储文件,而不是将转储文件作为参数。但是我不知道怎么做。

我想到了 运行 jmap -dump... 命令与运行时通过给 PID 但我不确定它是否是正确的方法。你能帮我吗?

使用Dynamic Attach API.

您仍然需要指定保存转储的文件名。

import com.sun.tools.attach.VirtualMachine;
import sun.tools.attach.HotSpotVirtualMachine;

import java.io.InputStream;

public class HeapDump {

    public static void main(String[] args) throws Exception {
        String pid = args[0];
        HotSpotVirtualMachine vm = (HotSpotVirtualMachine) VirtualMachine.attach(pid);

        try (InputStream in = vm.dumpHeap("/tmp/heapdump.hprof")) {
            byte[] buf = new byte[200];
            for (int bytes; (bytes = in.read(buf)) > 0; ) {
                System.out.write(buf, 0, bytes);
            }
        } finally {
            vm.detach();
        }
    }
}

如果您想避免引用 sun. … class,这里是 JMX API 变体:

private static void dumpHeap(String pid, String targetFile) throws Exception {
    VirtualMachine vm = VirtualMachine.attach(pid);
    String connectorAddress = vm.startLocalManagementAgent();
    JMXConnector c = JMXConnectorFactory.connect(new JMXServiceURL(connectorAddress));
    MBeanServerConnection sc = c.getMBeanServerConnection();
    sc.invoke(ObjectName.getInstance("com.sun.management:type=HotSpotDiagnostic"),
        "dumpHeap",
        new Object[] { targetFile, true }, new String[]{ "java.lang.String", "boolean" });
}

布尔参数对应于“live”参数,另见HotSpotDiagnosticMXBean.dumpHeap