2010-02-01 20 views
23

मैं सामान्य की तलाश नहीं कर रहा हूं "आप केवल System.gc() का उपयोग कर जावा में जीसी को संकेत दे सकते हैं" उत्तर, यह सवाल यह नहीं है कि यह सवाल क्या है।जावा: आप JVMTI के ForceGargabeCollection का उपयोग करके वास्तव में जीसी को कैसे मजबूर करते हैं?

मेरे प्रश्न व्यक्तिपरक नहीं हैं और वास्तविकता पर आधारित हैं: जीसी को जावा में एक तथ्य के लिए मजबूर किया जा सकता है। हमारे द्वारा दैनिक रूप से उपयोग किए जाने वाले कई कार्यक्रम इसे करते हैं: इंटेलिजे आईडीईए, नेटबीन, विजुअलVM।

वे सभी बल जीसी होने के लिए कर सकते हैं।

यह कैसे किया जाता है?

मुझे लगता है कि वे सभी JVMTI का उपयोग कर रहे हैं और अधिक विशेष रूप से फोर्सगर्बेज चयन ("बल" देखें) लेकिन मैं इसे अपने लिए कैसे कोशिश कर सकता हूं?

http://java.sun.com/javase/6/docs/platform/jvmti/jvmti.html#ForceGarbageCollection

भी ध्यान रखें कि इस सवाल के बारे "क्यों" मैं ऐसा करना चाहते हैं, हम उसे नहीं है: "एक कार्यक्रम VisualVM के लिए इसी तरह हम लिख रहे हैं" "क्यों" "जिज्ञासा" या हो सकता है, आदि

सवाल वास्तव में है "आप JVMTI के ForceGarbageCollection का उपयोग करके जीसी को कैसे मजबूर करते हैं"?

क्या JVM को किसी विशेष पैरामीटर के साथ लॉन्च करने की आवश्यकता है?

क्या कोई जेएनआई आवश्यक है? यदि हां, तो वास्तव में कौन सा कोड?

क्या यह केवल सूर्य वीएम पर काम करता है?

कोई भी पूर्ण और संकलित उदाहरण का स्वागत किया जाएगा।

उत्तर

10

नेटबीन, कम से कम, System.gc(): http://hg.netbeans.org/main/annotate/9779f138a9c9/openide.actions/src/org/openide/actions/GarbageCollectAction.java का उपयोग करता है (यह उस छोटे बटन के लिए है जो वर्तमान ढेर दिखाता है और आपको जीसी शुरू करने देता है)। यदि आप उस लिंक का पालन करते हैं, तो आप देखेंगे कि वे स्पष्ट रूप से अंतिम रूप से चलाते हैं। यदि आपके पास डिस्क स्पेस के कुछ गिग हैं, और यह कोड की जांच करना चाहते हैं, तो यह Mercurial के माध्यम से उपलब्ध है: hg clone http://hg.netbeans.org/main/

जहां तक ​​मैं कह सकता हूं, "System.gc() केवल एक संकेत है" dogma origates जेएलएस और जेवीएम स्पेक की पैडेंटिक व्याख्या में, जो जावा कार्यान्वयन की अनुमति देता है जिसमें कचरा-एकत्रित ढेर नहीं होता है। JavaDoc की यही कारण है, और एक अधूरी पढ़ने:

जीसी विधि कॉलिंग पता चलता है कि जावा वर्चुअल मशीन व्यय प्रयास क्रम में अप्रयुक्त वस्तुओं रीसाइक्लिंग की ओर स्मृति वे वर्तमान में त्वरित पुन: उपयोग के लिए उपलब्ध बनाने के लिए कब्जा । जब विधि कॉल से नियंत्रण रिटर्न मिलता है, तो जावा वर्चुअल मशीन ने सभी छोड़े गए ऑब्जेक्ट्स से स्थान को पुनः प्राप्त करने का सर्वोत्तम प्रयास किया है।

दूसरी वाक्य पढ़ें: "अंतरिक्ष पुनः प्राप्त करने का सबसे अच्छा प्रयास" "संकेत" से बहुत मजबूत है।

उस ने कहा, System.gc() पर कॉल करने का शायद ही कोई कारण है।नुथ के लिए क्षमा याचना के साथ:

हम स्मृति प्रबंधन के बारे में भूल जाना चाहिए, का कहना है कि समय की 97%: स्पष्ट कचरा संग्रहण बुराई सब की जड़ है

+2

मैं इसे एक हठधर्मिता एक पंडिताऊ व्याख्या के आधार पर फोन नहीं होता। वहां अधिकांश जेवीएम सिस्टम Systemcc() पर कॉल को अक्षम करना संभव बनाता है, इसलिए आप इसे करने के लिए विश्वास नहीं कर सकते हैं। काफी बार जहां आपके पास एक अच्छी तरह लिखित ऐप है जहां जीसी मजेदार काम कर रहा है, एक लाइब्रेरी पेश कर रहा है जहां डेवलपर ने सोचा था कि वह सिस्टम.gc() को कॉल करके "सुनिश्चित कर सकता है कि स्मृति उपलब्ध है", इसे बंद करना सबसे अच्छा तरीका है अपने अच्छे जीसी प्रदर्शन वापस। – Fredrik

+0

उपयोगकर्ता पर अभी भी नियंत्रण है। हॉटस्पॉट वीएम के लिए आप या तो '-XX: + DisableExplicitGC' सेट कर सकते हैं या आप नहीं करते हैं। इसलिए जब तक आप JVM झंडे 'System.gc() 'पर नियंत्रण रखते हैं, काफी विश्वसनीय है। तर्क केवल लाइब्रेरी लेखकों पर लागू होता है जो उन झंडे को नियंत्रित नहीं कर सकते हैं/यह नहीं मान सकते कि यह कौन सा वीएम चलाएगा। यह एक सामान्य मामला (spec) बनाम ठोस उपयोग (उपयोगकर्ता द्वारा नियंत्रित सभी पैरामीटर के साथ) चीज है। – the8472

+0

आवेदन लेखकों के पास आमतौर पर जेवीएम झंडे का नियंत्रण नहीं होता है। अपवाद तब होता है जब एप्लिकेशन लॉन्चर में लपेटा जाता है जो उपयोगकर्ता या sysadmin को tweaking से रोकता है। यह पैडेंट्री नहीं है। वास्तव में, ध्वज विशेष रूप से जावा अनुप्रयोगों/अनुप्रयोग लेखकों के खिलाफ बेवकूफ चीजों को करने के लिए लोगों की रक्षा के लिए है। –

0

हाँ JNI इंटरफ़ेस कोड JVMTI का उपयोग करने की जरूरत है एपीआई के रूप में यह एक मूल एपीआई है। "मूल" का अर्थ है कि आप इसे केवल मूल रूप से देशी (अंडरस्तान सी या सी ++) कोड बना सकते हैं। इसलिए यदि आप इस एपीआई को जावा से कॉल करना चाहते हैं तो आपको इसे इंटरफ़ेस करने के लिए जेएनआई कोड लिखना होगा।

0

जैसा कि एनन ने कहा है, हमारे पास कचरा कलेक्टर को स्पष्ट रूप से चलाने के लिए ग्रहण में कुछ समान है।

कृपया Eclipse: Garbage Collector Button

पर एक नज़र यह काफी अच्छी तरह से काम करने लगता है है। मेरा सुझाव है कि आप इस "कचरा कलेक्टर चलाएं" बटन के पीछे कोड देखें और इसका पुन: उपयोग करें।

कुछ सदस्य कहते हैं कि यह System.gc() का उपयोग करता है लेकिन मैं इसकी पुष्टि नहीं कर सकता। ग्रहण विशेषज्ञ यहां कुछ प्रकाश डाल सकते हैं।

#include <stdlib.h> 
#include <stdio.h> 
#include <jvmti.h> 


typedef struct { 
jvmtiEnv *jvmti; 
} GlobalAgentData; 

static GlobalAgentData *gdata; 

JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) 
{ 
    printf("load garbager agent\n"); 
    jvmtiEnv *jvmti = NULL; 

    // put a jvmtiEnv instance at jvmti. 
    jint result = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1); 
    if (result != JNI_OK) { 
    printf("ERROR: Unable to access JVMTI!\n"); 
    } 

    // store jvmti in a global data 
    gdata = (GlobalAgentData*) malloc(sizeof(GlobalAgentData)); 
    gdata->jvmti = jvmti; 
    return JNI_OK; 
} 


extern "C" 
JNIEXPORT void JNICALL Java_Garbager_forceGarbageCollection(JNIEnv *env, jclass thisClass) 
{ 
    printf("force garbage collection\n"); 
    gdata->jvmti->ForceGarbageCollection(); 
} 

इस एजेंट JNI के माध्यम से शुरू हो जाती है:

class Garbager { 
    public static void main(String[] args) { 
     Garbager.garbageMemory(); 
    } 

    static void garbageMemory() { 
     forceGarbageCollection(); 
    } 

    private static native void forceGarbageCollection(); 
} 

MacOSX पर एजेंट को संकलित करने के लिए:

4

मैं एक बुनियादी जावा एजेंट jvmti ForceGarbageCollection समारोह को लागू करने की अनुमति देता है बनाया

clang -shared -undefined dynamic_lookup -o garbager-agent.so -I /Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home/include/ -I /Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home/include/darwin garbager-agent.cpp 

Garbager लॉन्च करने के लिए:

java -agentpath:garbager-agent.so Garbager 

इस ट्यूटोरियल के आधार पर: Own your heap: Iterate class instances with JVMTI

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