java 从应用程序内部创建堆转储,无需 HotSpotDiagnosticMXBean

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12295824/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 08:20:35  来源:igfitidea点击:

create heap dump from within application, without HotSpotDiagnosticMXBean

javajmxheap-dump

提问by Chriss

How can i create a heap dump from within my application, without using the class HotSpotDiagnosticMXBean. Due to access restriction of java/rt.jari am not able to compile it with a dependency to HotSpotDiagnosticMXBean. I know how solve the eclipse.compiler error, but how can i fix it for my build? Is there an alternative to way to create a heap dump programmatically?

如何在不使用 HotSpotDiagnosticMXBean 类的情况下从我的应用程序中创建堆转储。由于访问限制,java/rt.jar我无法编译它依赖于HotSpotDiagnosticMXBean. 我知道如何解决 eclipse.compiler 错误,但我如何为我的构建修复它?有没有其他方法可以以编程方式创建堆转储?

回答by Doug

Okay,seems like you can bypass the restriction by using reflection :

好的,似乎您可以通过使用反射来绕过限制:

package lab.heapdump;

import javax.management.MBeanServer;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;


@SuppressWarnings("restriction")
public class HeapDump {
    // This is the name of the HotSpot Diagnostic MBean
    private static final String HOTSPOT_BEAN_NAME =
         "com.sun.management:type=HotSpotDiagnostic";

    // field to store the hotspot diagnostic MBean 
    private static volatile Object hotspotMBean;

    /**
     * Call this method from your application whenever you 
     * want to dump the heap snapshot into a file.
     *
     * @param fileName name of the heap dump file
     * @param live flag that tells whether to dump
     *             only the live objects
     */
    static void dumpHeap(String fileName, boolean live) {
        // initialize hotspot diagnostic MBean
        initHotspotMBean();
        try {
            Class clazz = Class.forName("com.sun.management.HotSpotDiagnosticMXBean");
            Method m = clazz.getMethod("dumpHeap", String.class, boolean.class);
            m.invoke( hotspotMBean , fileName, live);
        } catch (RuntimeException re) {
            throw re;
        } catch (Exception exp) {
            throw new RuntimeException(exp);
        }
    }

    // initialize the hotspot diagnostic MBean field
    private static void initHotspotMBean() {
        if (hotspotMBean == null) {
            synchronized (HeapDump.class) {
                if (hotspotMBean == null) {
                    hotspotMBean = getHotspotMBean();
                }
            }
        }
    }

    // get the hotspot diagnostic MBean from the
    // platform MBean server
    private static Object getHotspotMBean() {
        try {
            Class clazz = Class.forName("com.sun.management.HotSpotDiagnosticMXBean");
            MBeanServer server = ManagementFactory.getPlatformMBeanServer();
            Object bean = 
                ManagementFactory.newPlatformMXBeanProxy(server,
                HOTSPOT_BEAN_NAME, clazz);
            return bean;
        } catch (RuntimeException re) {
            throw re;
        } catch (Exception exp) {
            throw new RuntimeException(exp);
        }
    }

    public static void main(String[] args) {
        // default heap dump file name
        String fileName = "D:\heap.bin";
        // by default dump only the live objects
        boolean live = true;

        // simple command line options
        switch (args.length) {
            case 2:
                live = args[1].equals("true");
            case 1:
                fileName = args[0];
        }

        // dump the heap
        dumpHeap(fileName, live);
    }
}

回答by Zedong

package ru.test;

import com.sun.management.HotSpotDiagnosticMXBean;
import org.junit.Test;

import java.io.IOException;
import java.lang.management.ManagementFactory;

public class TestDump {
    @Test
    public void test() throws IOException {
        long i = 6789;
        String s = "HELLO";
        System.out.println(i);
        System.out.println(s);

        HotSpotDiagnosticMXBean mxBean = ManagementFactory.newPlatformMXBeanProxy(ManagementFactory.getPlatformMBeanServer(),
                "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class);
        mxBean.dumpHeap("C:\temp\dump\heap1.bin", true);
    }
}

Out:

出去:

6789
HELLO    


Process finished with exit code 0

回答by Kumar

You can copy the rt.jar which has the HotSpotDiagnosticMXBean.class to a different location. Refer the copied jar in build path using "Add External jar". This allows you to create Object and get the Heap dump.

您可以将包含 HotSpotDiagnosticMXBean.class 的 rt.jar 复制到其他位置。使用“添加外部 jar”在构建路径中引用复制的 jar。这允许您创建对象并获取堆转储。

new HotSpotDiagnostic().dumpHeap("d:\HeapDump1",true);

I was able to generate Heapdump this way. I was looking for any runtime conflict of jars error. Luckily none.

我能够以这种方式生成 Heapdump。我正在寻找 jars 错误的任何运行时冲突。幸好没有。

回答by Doug

VisualVM can make a heap dump.

VisualVM 可以进行堆转储。

You can also try the jhat command on linux systems.

您也可以在 linux 系统上尝试 jhat 命令。

回答by Peter Lawrey

This class is public, so the only reason you might not have access to it is you don't have it in your version of the JVM as its too old.

此类是公共的,因此您可能无法访问它的唯一原因是您的 JVM 版本中没有它,因为它太旧了。

The example linked to compiles and runs fine in Java 6 and 7. If possibly, try upgrading to a recent version of Java.

链接到的示例在 Java 6 和 7 中编译并运行良好。如果可能,请尝试升级到 Java 的最新版本。