2012-09-06 46 views
9

के बिना एप्लिकेशन के भीतर हीप डंप बनाएं, मैं हॉटस्पॉट डायग्नोस्टिक एमएक्सबीन क्लास का उपयोग किए बिना अपने एप्लिकेशन के भीतर से एक हीप डंप कैसे बना सकता हूं। java/rt.jar तक पहुंच प्रतिबंध के कारण मैं इसे HotSpotDiagnosticMXBean पर निर्भरता के साथ संकलित करने में सक्षम नहीं हूं। मुझे पता है कि eclipse.compiler त्रुटि को कैसे हल करें, लेकिन मैं इसे अपने निर्माण के लिए कैसे ठीक कर सकता हूं? क्या एक ढेर डंप प्रोग्रामेटिक रूप से बनाने का कोई विकल्प है?हॉटस्पॉट डायग्नोस्टिक एमएक्सबीन

  • यह समाधान काम नहीं करता है, की वजह से यह HotSpotDiagnosticMXBean निर्भरता है: HotSpot-dependent Heap Dump
+0

क्या आपने इसे पढ़ा: http://java.sun.com/developer/technicalArticles/J2SE/monitoring/? –

+0

क्या आप एक्सेस प्रतिबंध नहीं उठा सकते हैं ताकि आप इसे जिस तरह से करना चाहते हैं, कर सकें? या तो आपको यह करने की ज़रूरत है और आपके पास पहुंच हो सकती है या आप ऐसा नहीं करते हैं जिस स्थिति में आपको कोशिश नहीं करनी चाहिए। –

+0

@ पीटर लॉरी मैं प्रतिबंध नहीं उठा सकता (शायद एक कंपाइलर विकल्प है?) दूसरा विकल्प हैप डंप को दूसरी तरफ ट्रिगर करना है। – Chriss

उत्तर

14

ठीक है, लगता है कि आपके प्रतिबिंब का उपयोग करके प्रतिबंध बायपास कर सकते हैं:

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); 
    } 
} 
+0

प्रतिबिंब काम करता है! किसी को केवल यह जांचना है कि 'हॉटस्पॉटडिग्नोस्टिक एमएक्सबीन' क्लास वर्तमान जेडीके में उपलब्ध है या नहीं। – Chriss

+0

को https://blogs.oracle.com/sundararajan/entry/programmatically_dumping_heap_from_java –

+0

से अनुकूलित किया गया है, क्या आपको यकीन है कि यह काम करेगा? अगर मैं इसे लिखता हूं: getMethod ("dumpHeap", String.class, boolean.class) .. मुझे त्रुटि मिलती है "तर्क स्ट्रिंग, कक्षा , कक्षा " के लिए लागू नहीं है ... इसलिए मुझे सरणी का उपयोग करना है: नई कक्षा [ ] {स्ट्रिंग.क्लास, boolean.class} दूसरे पैरामीटर के रूप में और invoking इस तरह किया जाता है: m.invoke (हॉटस्पॉट एमबीएन, नया ऑब्जेक्ट [] {fileName, Boolean.valueOf (लाइव)}); – Racky

0

VisualVM एक ढेर डंप कर सकते हैं।

आप लिनक्स सिस्टम पर jhat कमांड को भी आजमा सकते हैं।

+1

मुझे पता है, लेकिन मैं बाहरी प्रोग्राम की आवश्यकता के बिना, मेरे आवेदन के भीतर से एक हेपडम्प ट्रिगर करना चाहता हूं। – Chriss

0

यह कक्षा सार्वजनिक है, इसलिए एकमात्र कारण यह है कि आपको इसका उपयोग नहीं हो सकता है, यह आपके पुराने संस्करण के रूप में JVM के आपके संस्करण में नहीं है।

उदाहरण 6 से 7 और 7 में ठीक से संकलित और चलाता है। यदि संभवतः जावा के हाल के संस्करण में अपग्रेड करने का प्रयास करें।

+2

मैं जावा 7 का उपयोग कर रहा हूं। समस्या यह है कि HotSpotDiagnosticMXBean सार्वजनिक HotSpotDiagnosticMXBean क्लास नहीं है (यह jdk का हिस्सा नहीं है)। यह वर्ग केवल ओरेकल जावा वितरण में मौजूद है, यह जेवीएम निर्भर है। – Chriss

+0

इसका मतलब यह है कि सुविधा JVM निर्भर है और आप कोड संकलित कर सकते हैं, लेकिन यह JVMs पर नहीं चल सकता है जो इस सुविधा का समर्थन नहीं करते हैं। आप जेवीएम के किस स्वाद का उपयोग कर रहे हैं? –

0

आप rt.jar जो किसी दूसरे स्थान पर HotSpotDiagnosticMXBean.class है कॉपी कर सकते हैं। "बाहरी जार जोड़ें" का उपयोग करके निर्मित पथ में कॉपी किए गए जार का संदर्भ लें। यह आपको ऑब्जेक्ट बनाने और हीप डंप प्राप्त करने की अनुमति देता है।

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

मैं इस तरह हेपडम्प उत्पन्न करने में सक्षम था। मैं जार त्रुटि के किसी भी रनटाइम संघर्ष की तलाश में था। सौभाग्य से कोई नहीं।

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^