2009-09-04 14 views
13

हमारे पास जावा में कोई विनाशक नहीं है जैसा कि हमारे पास सी ++ है।जावा में ऑब्जेक्ट को साफ़ करने का सबसे अच्छा तरीका क्या है?

प्रश्न 1। हमें जावा में किसी ऑब्जेक्ट को कैसे साफ करना चाहिए।

प्रश्न 2। क्या आखिरकार ब्लॉक के लिए कोई विकल्प है।

क्यू 3। कभी-कभी हमें अपनी कक्षा से किसी तृतीय पक्ष कोड के स्पष्ट रूप से प्रारंभिकरण/समाप्ति को कॉल करना होता है उदा।

public classs MyClass{ 
    public MyClass(){ 
     ThirdPartyInitialize(); 
    } 

    protected void finalize(){ 
     ThirdPartyTerminate(); 
    } 
} 

क्या यह सही तरीका है?

उत्तर

12

आप आमतौर पर जावा ऑब्जेक्ट्स को "साफ" नहीं कर सकते हैं। कचरा कलेक्टर तय करता है कि वस्तुओं को साफ करने के लिए कब। आप इंगित कर सकते हैं कि जब आप किसी ऑब्जेक्ट संदर्भ के साथ null पर सेट करके किया जाता है, लेकिन आम तौर पर इसे केवल दायरे से बाहर जाने देना पर्याप्त होता है। किसी भी तरह से, जब भी कचरा इकट्ठा होता है तब भी आपका कोई नियंत्रण नहीं होता है।

finally ब्लॉक क्रियाओं को करने के लिए है कि क्या try ब्लॉक से अपवाद फेंक दिया गया है या नहीं, और साफ करने के लिए सबसे अच्छी जगह है। आम तौर पर आप केवल ओपन स्ट्रीम जैसे गैर-ऑब्जेक्ट संसाधनों को साफ़ कर देंगे।

finalize() को कॉल करने की गारंटी नहीं है क्योंकि कचरा कलेक्टर को आपके प्रोग्राम से बाहर जाने से पहले बुलाया जाने की गारंटी नहीं है। यह वास्तव में एक सी ++ विनाशक की तरह नहीं है क्योंकि सी ++ विनाशकों को हमेशा बुलाया जाता है और आप उन पर भरोसा कर सकते हैं जिन्हें बुलाया जा रहा है। आप finalize() पर भरोसा नहीं कर सकते हैं।

तो 1) finally ब्लॉकों का उपयोग करें) गैर वस्तु संसाधनों 2 रिलीज कचरा कलेक्टर वस्तु संसाधनों 3 को साफ करते हैं) आप कचरा कलेक्टर है कि आप null को निर्धारित कर उसे एक वस्तु के साथ किया जाता है करने के लिए संकेत कर सकते हैं अगर यह एक लंबी चल रही विधि में प्रयोग किया जाता है।

0

अंतिम रूप एक विनाशक के समान उपयोग किया जाता है, लेकिन, यदि आप प्रयास का उपयोग करते हैं ... आखिर में संसाधनों के लिए ब्लॉक करें, तो आप संसाधन खोल सकते हैं और आखिर में ब्लॉक को संसाधन बंद कर सकते हैं।

आखिरकार ब्लॉक हमेशा कॉल किया जाता है, जब ब्लॉक बाहर निकलता है, या तो सामान्य रूप से या अपवाद को फेंक दिया जाता है।

अंतिमकरण संसाधन प्रबंधन के लिए जोखिम भरा है, क्योंकि आपको नहीं पता कि इसे कब कहा जाएगा, और यदि यह किसी ऑब्जेक्ट को बंद कर देता है जिसे अंतिम रूप दिया गया है तो इसमें कुछ समय लग सकता है।

आखिरकार ब्लॉक बेहतर दृष्टिकोण है।

+0

मैं * नहीं * कहूँगा कि अंतिम रूप देने() एक नाशक के समान है। आपका बाकी का पाठ ठीक है, लेकिन यह बड़े पैमाने पर पहले बयान के विपरीत है। आप कभी नहीं जानते कि अंतिम रूप कब() कहा जाएगा। तो यह एक सी ++ विनाशक के विपरीत है, जिसे किसी ऑब्जेक्ट को दायरा छोड़ दिया जाता है या हटा दिया जाता है। –

+0

जब कोई ऑब्जेक्ट कचरा इकट्ठा होता है तो फाइनल को बुलाया जाएगा, लेकिन कोई कचरा नहीं होगा जब यह कचरा इकट्ठा किया जाएगा, इसलिए अंतिमकर्ता को समय-समय पर नहीं बुलाया जा सकता है। –

5

आप अपने कार्यक्रम के लिए एक shutdown hook जोड़ सकता है, तो अपने कार्यक्रम भी बंद हो रहा है:

//add shutdown hook 
Runtime.getRuntime().addShutdownHook(new Thread() { 
    public void run() { 
     ThirdPartyTerminate(); 
    } 
}); 
1

A1। यदि आपको किसी ऑब्जेक्ट को प्रारंभ करना है, तो Dispose pattern is the way to go

ए 2। संसाधन प्रबंधन बिंदु से, वहां नहीं है। यह ध्यान दिया जाना चाहिए कि अंततः ब्लॉक एक निर्धारिक संसाधन प्रबंधन नहीं है।

ए 3। हां, यह सही तरीका है।

2

ऑब्जेक्ट्स के बाद साफ करने का सबसे अच्छा तरीका ऑब्जेक्ट को छोड़ना है।

अंत में ब्लॉक को मुहावरे के बाहर निष्पादन का उपयोग करके सारणित किया जा सकता है।

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

+0

प्रदर्शन के बीच कोई संबंध है और अंत में ब्लॉक? – pankajt

+0

मुझे यकीन नहीं है कि आपका क्या मतलब है। यदि आप तुरंत संसाधन जारी नहीं करते हैं तो आपके पास संभावित समस्याएं हैं (और न केवल प्रदर्शन)। यदि आप अपवाद नहीं फेंक रहे हैं, तो किसी भी उचित अपवाद पर लागू करने से यह थोड़ा अंतर होता है कि कोई प्रयास ब्लॉक है या नहीं (यह अधिकांश सी ++ कार्यान्वयन से अलग है)। यदि अंत में ब्लॉक की सामग्री धीमी है, तो यह पूल में लौटने लायक हो सकता है (भले ही "पूल" सिर्फ एक अलग थ्रेड में संसाधन जारी करता हो)। –

1

Here's अंतिमकर्ताओं के बारे में अच्छी जानकारी।

1

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


C a = new C(); //create an object of class C and assign it to 'a' 
a = new C(); //create another object of class C and assign it to 'a'. The older object is no longer referred to. It is now eligible for GC. 

अंतिम रूप देने के बेहतर विकल्प() के आधार कितना को अंतिम रूप देने() अपनी स्थिति मदद कर रहा है पर कर रहे हैं।

अक्सर, सबसे अच्छा अभ्यास एपीआई में करीबी() या निपटान स्रोत() जैसी विधि प्रदान करना है जो कॉलर को एपीआई को स्वयं को साफ करने में मदद करने की अनुमति देगा। उदाहरण के लिए, java.sql.Connection class does this। यह अंतिम() विधि से बेहतर है, क्योंकि JVM अंतिम() विधि को कॉल करेगा। अक्सर अंतिम() विधि JVM में कम प्राथमिकता वाले थ्रेड द्वारा चलाया जाएगा, जिससे कुछ अजीब त्रुटियां हो सकती हैं।

कनेक्शन वर्ग के मामले में, जेवीएम को अंतिम रूप देने के लिए इंतजार करना बहुत सारे अनुप्रयोगों में महंगा साबित होता है, क्योंकि डेटाबेस एक समय में केवल इतना कनेक्शन स्वीकार कर सकता है। इसलिए, अधिकांश प्रोग्रामर एक कनेक्शन ऑब्जेक्ट पर स्पष्ट रूप से() को कॉल करेंगे।

आपके मामले में, यह कुछ ऐसा ही में अनुवाद करना चाहिए (और इस संदर्भ में, अंत में ब्लॉक हमेशा चलाने के लिए गारंटी है)


try 
{ 
ThirdPartyInitialize(); 
// use third party component in this try block 
} 
finally 
{ 
ThirdPartyTerminate(); 
} 

इस के समान है कैसे कनेक्शन वर्ग भी सबसे में प्रयोग किया जाता है स्थितियों।

-1

जावा में आपकी ऑब्जेक्ट्स को वास्तव में "साफ अप" होने की आवश्यकता नहीं है, जीसी बस काम करता है। लगभग हर बार मैंने कोड में कुछ ऑब्जेक्ट = शून्य देखा है, यह ऐसा कोई व्यक्ति है जो नहीं जानता था कि वे क्या कर रहे थे। इसके लिए एक सैद्धांतिक मामला है, लेकिन यह वास्तव में एक बढ़त का मामला है और आमतौर पर संसाधनों के साथ हाल ही में जोड़े गए प्रयासों जैसे अन्य तरीकों से बेहतर तरीके से संभाला जाता है।

यदि आपके पास कोई बाहरी संसाधन है जिसे किसी ऑब्जेक्ट का उपयोग नहीं किया जाता है, तो यह एक और मामला है।

वहां "संदर्भ" कक्षाएं हैं जो आपकी कक्षा में एक विशेष प्रकार का संदर्भ रखती हैं - यह कचरा संग्रह नहीं रोकती है, लेकिन जब वर्ग कचरा इकट्ठा होता है तो आपको सूचित कर सकता है (यदि आपको पसंद है तो कॉलबैक के माध्यम से)। वीक रेफरेंस, फैंटॉम रिफरेंस इत्यादि देखें

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

+0

यह उपर्युक्त प्रश्न का उत्तर नहीं है क्योंकि आप अनिवार्य रूप से उन्हें अपनी वस्तुओं को साफ न करने के लिए कह रहे हैं। बहुत सारे उदाहरण हैं (विशेष रूप से जब इवेंट बस और थ्रेड वैरिएबल का उपयोग करते हैं) जहां वस्तुओं को साफ करने और इन प्रकार के सिस्टम के लिए अनियंत्रित करने की आवश्यकता होती है। यदि आप बहुत ही सरल pojos का उपयोग कर रहे हैं, तो हाँ आपको ज्यादा करने की आवश्यकता नहीं है। हालांकि, किसी भी दूरस्थ रूप से जटिल कार्य को रिसाव वस्तुओं के लिए मूल्यांकन करने की आवश्यकता है क्योंकि यह समुदाय में मुद्दों के प्रमुख कारण के रूप में आज है। – dsutherland

+0

दरअसल, जावा वस्तुओं के एक बड़े सौदे के लिए आपको क्लीनअप विधि कॉल करने की आवश्यकता होती है। 'Obj.open (...); Obj.close(); ' – iPherian

1

दो वाक्य रचना चीनी विकल्प:

@Cleanup 
ResourceClass resource = new ResourceClass(); 

2) वहाँ भी try-with-resources कथन है:

1) वहाँ लंबोक की एक @Cleanup एनोटेशन ज्यादातर जैसा दिखता है कि सी ++ विनाशकर्ता (more) है। उदाहरण के लिए:

try (BufferedReader br = new BufferedReader(new FileReader(path))) { 
    System.out.println(br.readLine()); 
} 
संबंधित मुद्दे

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