create heap dump from within application, without HotSpotDiagnosticMXBean
Asked Answered
C

5

17

How can i create a heap dump from within my application, without using the class HotSpotDiagnosticMXBean. Due to access restriction of java/rt.jar i 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?

Crippen answered 6/9, 2012 at 8:19 Comment(3)
did you read this: java.sun.com/developer/technicalArticles/J2SE/monitoring ?Bandaranaike
Can you not lift the access restriction so you can do it the way you are supposed to? Either you need to do this and you can have access or you don't in which case you shouldn't try.Cumming
@Peter Lawrey i can't lift the restriction (maybe there is a compiler option?) the second option is to trigger a heap dump in a other way.Crippen
L
23

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);
    }
}
Lonilonier answered 6/9, 2012 at 9:47 Comment(3)
Reflection works! One have only to check if the HotSpotDiagnosticMXBean class is available in the current jdk.Crippen
Appears to have been adapted from blogs.oracle.com/sundararajan/entry/…Hypercorrection
Are you sure this will work? If I write this: getMethod("dumpHeap", String.class, boolean.class) .. I get error "not applicable for arguments String, Class<T>, Class<T>" ... so I have to use array: new Class[] {String.class, boolean.class} as the 2nd parameter and invoking is done like this: m.invoke( hotspotMBean , new Object[] {fileName, Boolean.valueOf(live)});Dartboard
F
6
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
Frequentation answered 7/2, 2020 at 7:56 Comment(0)
Y
0

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.

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.

Ygerne answered 10/7, 2017 at 18:8 Comment(0)
L
-1

VisualVM can make a heap dump.

You can also try the jhat command on linux systems.

Lonilonier answered 6/9, 2012 at 8:28 Comment(1)
I know, but i want to trigger a heapdump from within my application, without the need of a external programm.Crippen
C
-1

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.

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

Cumming answered 6/9, 2012 at 8:54 Comment(2)
I'am using java7. The Problem is that HotSpotDiagnosticMXBean is not a public HotSpotDiagnosticMXBean class (it is not part of the jdk). This class exists only in the oracle java distribution, it is JVM dependent.Crippen
This means the feature is JVM dependent and you can compile the code, but it might not run on JVMs which don't support this feature. Which flavours of JVMs are you using?Cumming

© 2022 - 2024 — McMap. All rights reserved.