2012-01-09 23 views
5

किसी प्रोजेक्ट के लिए, हमें उपयोगकर्ता स्क्रिप्ट चलाने के लिए एक तरीका चाहिए जो अतिरिक्त कक्षाओं के साथ संलग्न JAR फ़ाइलों के साथ आ सकता है।मैं जीसी परीक्षण कैसे कर सकता हूं?

मेरे विकल्प क्या हैं जब मैं कुछ परीक्षण लिखना चाहता हूं ताकि यह सुनिश्चित किया जा सके कि सामान्य स्क्रिप्ट पीछे कुछ भी नहीं छोड़ती?

मुझे विशेष रूप से यह जानने की आवश्यकता है: संलग्न जेएआर के सभी वर्ग "अनलोड किए गए" हैं?

नोट: मैं 100% सुपर-वॉटरटाइट समाधान की तलाश नहीं कर रहा हूं जो जावा के सभी संस्करणों में 1.0 से 7 तक काम करता है। अभी, मुझे "मुझे कोई जानकारी नहीं है" से बेहतर होना चाहिए।

+0

वे क्यों उतार किया जाएगा कहते हैं? क्या आपका मतलब है कि उनके उदाहरण जीसीएड होंगे, यानी, उपयोगकर्ता स्क्रिप्ट के कोड और पुस्तकालयों में मेमोरी लीक नहीं है? क्या आप उन्हें एक नए वर्ग लोडर के साथ लोड कर रहे हैं? –

+0

हां। मैं क्या चाहता हूं जीसी से पूछने का एक तरीका है "क्या आप अभी इस उदाहरण को जीसी कर सकते हैं?" या शायद "मुझे बताएं कि उदाहरण के लिए कितने संदर्भ मौजूद हैं 'foo'" प्रोफाइलर इसे कैसे करते हैं? दूसरे विकल्प के लिए –

उत्तर

3

संभवतः सबसे अच्छा विकल्प यह सुनिश्चित करना है कि आपके लोड किए गए जार एक विशिष्ट वर्ग लोडर द्वारा लोड किए जाएं, और उसके बाद उस वर्ग लोडर को छोड़ दें (सभी ऑब्जेक्ट्स को छोड़कर)।

जहां तक ​​यूनिट अनलोडिंग का परीक्षण करता है, यदि आप इस विकल्प के साथ जाते हैं, तो आपको "परीक्षण लोडर ऑन डिमांड" ध्वज बनाने के लिए अपने परीक्षण ढांचे और अनुकूलित क्लास लोडर को विस्तारित करने की आवश्यकता है। फिर आप ध्वज के साथ कक्षा को एक बार लोड करते हैं, कक्षा लोडर को त्याग देते हैं, और ध्वज के साथ कक्षा को फिर से लोड करने का प्रयास करते हैं। यदि वर्ग वास्तव में पहुंच योग्य नहीं है, तो दूसरे प्रयास को कक्षा को फेंकना चाहिए अपवाद नहीं मिला। यदि आप अपवाद में पड़ते हैं तो आप अपने यूनिट परीक्षणों को पास करने के लिए लपेटते हैं, और विफल होते हैं यदि वे दूसरे लोड प्रयास के बाद लाइन को मारने में सफल होते हैं।

यदि आप शुद्ध-जावा उपकरणों से अधिक का उपयोग करने के लिए निपटाए गए हैं, तो ओएसजीआई कंटेनर एक विचार हो सकता है। अधिकांश स्थापित ओएसजीआई कंटेनर कार्यान्वयन स्पष्ट रूप से कक्षा अनलोडिंग का परीक्षण करते हैं।

+0

+1।100% सुनिश्चित करने के लिए (जो मुझे पता है कि आवश्यकता नहीं है), आपको शायद क्लास लोडर को एक सुरक्षा प्रबंधक के साथ चलाने की आवश्यकता होगी (यह सुनिश्चित करने के लिए कि स्क्रिप्ट्स ने धागे नहीं बनाए हैं, आदि)। –

+0

@ सेन रेली, धन्यवाद। अन्य विकल्प शोर बन गए, इसलिए मैंने संदेश को शीर्ष के करीब ले जाया। –

+0

प्रश्न का बिंदु यह प्रतीत होता है कि हारून पहले से ही आपके पहले अनुच्छेद में जो वर्णन करता है वह कर रहा है, लेकिन चूंकि आप जावा ऑब्जेक्ट्स को स्पष्ट रूप से त्याग नहीं सकते हैं, इसलिए वह यह जांचने का एक तरीका चाहता है कि यह वास्तव में पूर्ण रूप से हो रहा है या फिर कोई रिसाव है या नहीं। –

3

मैं इस परीक्षण का परीक्षण करने की कोशिश नहीं करता। इसके बजाए, मैं -XX: -TraceClassUnloading के साथ JVM चलाऊंगा और यह देखने के लिए देख सकता हूं कि प्रश्नों में कक्षाएं ट्रेस आउटपुट में दिखाई देती हैं या नहीं।

1

यह पूरी तरह से स्क्रिप्ट चलाने की अनुमति देने के तरीके पर निर्भर करता है। क्या उनके पास शेष एप्लिकेशन के वर्गों तक पहुंच है?

जावा में स्मृति को रिसाव करने का सामान्य तरीका एक स्थिर संदर्भ होना है। एक स्थिर संदर्भ कक्षा के क्लासलोडर के भीतर केवल स्थिर है जिसमें यह शामिल है। इसलिए, यदि आप क्लासलोडर का उपयोग करके अपनी उपयोगकर्ता स्क्रिप्ट लोड करते हैं तो आप स्वयं को प्रबंधित करते हैं (और आपको इसे वैसे भी करना चाहिए), तो अंदर दिए गए संदर्भ (स्थिर या नहीं) जैसे ही आपके क्लासलोडर के रूप में जीसी के लिए पात्र होंगे।

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

मुझे इसके लिए पूरी तरह से स्वचालित परीक्षण करने का कोई तरीका नहीं दिख रहा है। लेकिन मुझे लगता है कि आप किसी भी सभ्य प्रोफाइलर के साथ कक्षा को उतारने का पता लगा सकते हैं।

2

ऐसा लगता है कि आप परीक्षण करना चाहते हैं कि नली स्क्रिप्ट में classloader leak नहीं है।

कि ऐसा करने के लिए, मैं बनाएंगे, एक WeakReferenceClassLoader कि जार लोड करने के लिए है, तो चलाने स्क्रिप्ट का इस्तेमाल किया है, तो System.gc() और बाद में assertNull(reference.get())

+0

वैकल्पिक रूप से URLClassLoader प्रति JAR का उदाहरण बनाने के लिए एक विकल्प हो सकता है और कक्षाओं को लोड करने के लिए इसका उपयोग कर सकता है। इसे एक बार किया (इसे शून्य करने के लिए सेट)। – aishwarya

+1

@ ऐश्वर्या: यह बिल्कुल "वैकल्पिक" नहीं है। आप जावा वस्तुओं को "कचरा" नहीं कर सकते हैं। नल के संदर्भ को सेट करने से केवल ऑब्जेक्ट को कचरा होने की अनुमति मिलती है यदि कोई अन्य संदर्भ नहीं है। मैं जो वर्णन करता हूं वह यह है कि ऑब्जेक्ट * वास्तव में कचरा इकट्ठा किया गया था। क्लासलोडर से छुटकारा पाने के लिए कुख्यात रूप से कड़ी मेहनत होती है क्योंकि किसी संग्रह में छिपी हुई किसी भी लोडेड कक्षाओं में से किसी एक वस्तु का संदर्भ क्लासलोडर को रोकने के लिए पर्याप्त है और एकत्रित कचरा होने से सभी वर्गों को लोड किया जाता है। –

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