फ़ाइनलाइज़र: Difference between revisions
(Created page with "{{for|the video game|Finalizer (video game)}} {{for|the process related to optical disc media|Finalize (optical discs)}} कंप्यूटर विज्ञान म...") |
No edit summary |
||
Line 87: | Line 87: | ||
यदि उपयोगकर्ता द्वारा निर्दिष्ट फ़ाइनलाइज़र की अनुमति दी जाती है, तो अंतिमकरण के लिए ऑब्जेक्ट पुनरुत्थान का कारण संभव है, क्योंकि फ़ाइनलाइज़र मनमाना कोड चला सकते हैं, जो जीवित वस्तुओं से नष्ट होने वाली वस्तुओं के संदर्भ बना सकते हैं। कचरा संग्रह के बिना भाषाओं के लिए, यह एक गंभीर बग है, और झूलने वाले संदर्भों और [[स्मृति सुरक्षा]] उल्लंघनों का कारण बनता है; कचरा संग्रह वाली भाषाओं के लिए, इसे कचरा संग्रहकर्ता द्वारा रोका जाता है, आमतौर पर कचरा संग्रह में एक और कदम जोड़कर (सभी उपयोगकर्ता-निर्दिष्ट फ़ाइनलाइज़र चलाने के बाद, पुनरुत्थान की जाँच करें), जो कचरा संग्रह को जटिल और धीमा कर देता है। | यदि उपयोगकर्ता द्वारा निर्दिष्ट फ़ाइनलाइज़र की अनुमति दी जाती है, तो अंतिमकरण के लिए ऑब्जेक्ट पुनरुत्थान का कारण संभव है, क्योंकि फ़ाइनलाइज़र मनमाना कोड चला सकते हैं, जो जीवित वस्तुओं से नष्ट होने वाली वस्तुओं के संदर्भ बना सकते हैं। कचरा संग्रह के बिना भाषाओं के लिए, यह एक गंभीर बग है, और झूलने वाले संदर्भों और [[स्मृति सुरक्षा]] उल्लंघनों का कारण बनता है; कचरा संग्रह वाली भाषाओं के लिए, इसे कचरा संग्रहकर्ता द्वारा रोका जाता है, आमतौर पर कचरा संग्रह में एक और कदम जोड़कर (सभी उपयोगकर्ता-निर्दिष्ट फ़ाइनलाइज़र चलाने के बाद, पुनरुत्थान की जाँच करें), जो कचरा संग्रह को जटिल और धीमा कर देता है। | ||
इसके अलावा, वस्तु पुनरुत्थान का अर्थ है कि एक वस्तु को नष्ट नहीं किया जा सकता है, और पैथोलॉजिकल मामलों में एक वस्तु हमेशा अंतिम रूप देने के दौरान खुद को पुनर्जीवित कर सकती है, खुद को अविनाशी बना सकती है। इसे रोकने के लिए, कुछ भाषाएँ, जैसे जावा और पायथन (पायथन 3.4 से) केवल एक बार वस्तुओं को अंतिम रूप देती हैं, और पुनर्जीवित वस्तुओं को अंतिम रूप नहीं देती हैं। | इसके अलावा, वस्तु पुनरुत्थान का अर्थ है कि एक वस्तु को नष्ट नहीं किया जा सकता है, और पैथोलॉजिकल मामलों में एक वस्तु हमेशा अंतिम रूप देने के दौरान खुद को पुनर्जीवित कर सकती है, खुद को अविनाशी बना सकती है। इसे रोकने के लिए, कुछ भाषाएँ, जैसे जावा और पायथन (पायथन 3.4 से) केवल एक बार वस्तुओं को अंतिम रूप देती हैं, और पुनर्जीवित वस्तुओं को अंतिम रूप नहीं देती हैं। वस्तु-दर-वस्तु के आधार पर किसी वस्तु को अंतिम रूप दिया गया है या नहीं, यह ट्रैक करके ठोस रूप से किया जाता है। उद्देश्य-सी भी अंतिम रूप से ट्रैक करता है (कम से कम हाल ही में एप्पल संस्करण) समान कारणों से, पुनरुत्थान को बग के रूप में मानना। | ||
.NET फ्रेमवर्क में एक अलग दृष्टिकोण का उपयोग किया जाता है, विशेष रूप से C# और विजुअल बेसिक .NET, जहां अंतिम रूप को ऑब्जेक्ट के बजाय क्यू द्वारा ट्रैक किया जाता है। इस मामले में, यदि उपयोगकर्ता द्वारा निर्दिष्ट फाइनलाइज़र प्रदान किया जाता है, तो डिफ़ॉल्ट रूप से ऑब्जेक्ट को केवल एक बार अंतिम रूप दिया जाता है (यह निर्माण पर अंतिम रूप देने के लिए कतारबद्ध होता है, और इसे अंतिम रूप देने के बाद हटा दिया जाता है), लेकिन इसे कॉल करके बदला जा सकता है <code>GC</code> मापांक। कॉल करके अंतिम रूप से रोका जा सकता है <code>GC.SuppressFinalize</code>, जो ऑब्जेक्ट को डीक्यू करता है, या कॉल करके पुनः सक्रिय करता है <code>GC.ReRegisterForFinalize</code>, जो वस्तु को कतारबद्ध करता है। इनका विशेष रूप से उपयोग किया जाता है जब संसाधन प्रबंधन के लिए अंतिम रूप देने के लिए निपटान पैटर्न के पूरक के रूप में उपयोग किया जाता है, या ऑब्जेक्ट पूल को लागू करते समय। | .NET फ्रेमवर्क में एक अलग दृष्टिकोण का उपयोग किया जाता है, विशेष रूप से C# और विजुअल बेसिक .NET, जहां अंतिम रूप को ऑब्जेक्ट के बजाय क्यू द्वारा ट्रैक किया जाता है। इस मामले में, यदि उपयोगकर्ता द्वारा निर्दिष्ट फाइनलाइज़र प्रदान किया जाता है, तो डिफ़ॉल्ट रूप से ऑब्जेक्ट को केवल एक बार अंतिम रूप दिया जाता है (यह निर्माण पर अंतिम रूप देने के लिए कतारबद्ध होता है, और इसे अंतिम रूप देने के बाद हटा दिया जाता है), लेकिन इसे कॉल करके बदला जा सकता है <code>GC</code> मापांक। कॉल करके अंतिम रूप से रोका जा सकता है <code>GC.SuppressFinalize</code>, जो ऑब्जेक्ट को डीक्यू करता है, या कॉल करके पुनः सक्रिय करता है <code>GC.ReRegisterForFinalize</code>, जो वस्तु को कतारबद्ध करता है। इनका विशेष रूप से उपयोग किया जाता है जब संसाधन प्रबंधन के लिए अंतिम रूप देने के लिए निपटान पैटर्न के पूरक के रूप में उपयोग किया जाता है, या ऑब्जेक्ट पूल को लागू करते समय। |
Revision as of 09:10, 19 May 2023
कंप्यूटर विज्ञान में, एक फाइनलाइज़र या अंतिम विधि एक विशेष विधि (कंप्यूटर प्रोग्रामिंग) है जो अंतिम रूप देती है, आम तौर पर सफाई का कुछ रूप। वस्तु के विनाश के दौरान एक फाइनलाइज़र को निष्पादित किया जाता है, वस्तु निर्माण आवंटन रद्द से पहले, और एक प्रारंभकर्ता का पूरक होता है, जिसे मेमोरी प्रबंधन के बाद ऑब्जेक्ट निर्माण के दौरान निष्पादित किया जाता है। उचित उपयोग में कठिनाई और उनके द्वारा जोड़ी जाने वाली जटिलता के कारण फ़ाइनलाइज़र को कुछ लोगों द्वारा दृढ़ता से हतोत्साहित किया जाता है, और इसके बजाय विकल्प सुझाए जाते हैं, मुख्य रूप से निपटान पैटर्न[1] (#समस्याएं देखें)।
फ़ाइनलाइज़र शब्द का उपयोग ज्यादातर ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग में किया जाता है। ऑब्जेक्ट-ओरिएंटेड और कार्यात्मक प्रोग्रामिंग प्रोग्रामिंग भाषा जो कचरा संग्रह (कंप्यूटर साइंस) का उपयोग करती हैं, जिनमें से मूलरूप स्मॉलटाक है। यह एक विनाशक (कंप्यूटर प्रोग्रामिंग) के विपरीत है, जो नियतात्मक रूप से C++ के नियतात्मक वस्तु जीवनकाल के साथ भाषाओं में अंतिम रूप देने के लिए कहा जाने वाला एक तरीका है।[2][3] ये आम तौर पर अनन्य होते हैं: एक भाषा में या तो फ़ाइनलाइज़र (यदि स्वचालित रूप से कचरा एकत्र किया जाता है) या विध्वंसक (यदि मैन्युअल रूप से मेमोरी प्रबंधित की जाती है), लेकिन दुर्लभ मामलों में एक भाषा में C++/CLI और D (प्रोग्रामिंग लैंग्वेज) और दोनों हो सकते हैं। संदर्भ गिनती का मामला (कचरा संग्रह का पता लगाने के बजाय), शब्दावली भिन्न होती है। तकनीकी उपयोग में, डिस्ट्रक्टर्स को संदर्भित करने के लिए फाइनलाइज़र का भी उपयोग किया जा सकता है, क्योंकि ये भी अंतिम रूप देते हैं, और कुछ सूक्ष्म भेद तैयार किए जाते हैं - #Terminology देखें। अंतिम शब्द का उपयोग उस वर्ग को इंगित करने के लिए भी किया जाता है जो वंशानुक्रम (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) नहीं हो सकता है; यह असंबंधित है।
शब्दावली
फाइनलाइज़र और फ़ाइनलाइज़ेशन बनाम विध्वंसक और विनाश की शब्दावली लेखकों के बीच भिन्न होती है और कभी-कभी अस्पष्ट होती है।
सामान्य उपयोग में, एक विध्वंसक एक विधि है जिसे नियतात्मक रूप से वस्तु के विनाश पर कहा जाता है, और मूलरूप सी ++ विध्वंसक है; जबकि एक फाइनलाइज़र को कचरा कलेक्टर द्वारा गैर-नियतात्मक रूप से कहा जाता है, और मूलरूप जावा (प्रोग्रामिंग भाषा) है finalize
तरीके।
उन भाषाओं के लिए जो संदर्भ गिनती के माध्यम से कचरा संग्रह को लागू करती हैं, शब्दावली भिन्न होती है, कुछ भाषाओं जैसे उद्देश्य सी और पर्ल डिस्ट्रक्टर का उपयोग करते हुए, और अन्य भाषाओं जैसे कि पायथन फ़ाइनलाइज़र का उपयोग करते हुए (प्रति युक्ति, पायथन कचरा एकत्र किया जाता है, लेकिन संदर्भ CPython कार्यान्वयन इसके बाद से संस्करण 2.0 संदर्भ गिनती और कचरा संग्रह के संयोजन का उपयोग करता है)। यह दर्शाता है कि संदर्भ गणना का परिणाम अर्ध-नियतात्मक वस्तु जीवनकाल में होता है: उन वस्तुओं के लिए जो एक चक्र का हिस्सा नहीं हैं, वस्तुओं को निश्चित रूप से नष्ट कर दिया जाता है जब संदर्भ संख्या शून्य हो जाती है, लेकिन एक चक्र का हिस्सा होने वाली वस्तुओं को गैर-नियतात्मक रूप से नष्ट कर दिया जाता है। कचरा संग्रह के एक अलग रूप का हिस्सा।
कुछ संकीर्ण तकनीकी उपयोगों में, कंस्ट्रक्टर और डिस्ट्रक्टर भाषा-स्तर के शब्द हैं, जिसका अर्थ है कि एक वर्ग में परिभाषित विधियाँ, जबकि इनिशियलाइज़र और फ़ाइनलाइज़र कार्यान्वयन-स्तर की शर्तें हैं, जिसका अर्थ है वस्तु निर्माण या विनाश के दौरान बुलाई जाने वाली विधियाँ। इस प्रकार उदाहरण के लिए सी शार्प (प्रोग्रामिंग भाषा) के लिए मूल विनिर्देश | सी # भाषा विनाशकों को संदर्भित करती है, भले ही सी # कचरा-एकत्रित है, लेकिन सामान्य भाषा इंफ्रास्ट्रक्चर (सीएलआई) के लिए विनिर्देश, और इसके रनटाइम पर्यावरण के कार्यान्वयन के रूप में सामान्य भाषा रनटाइम (सीएलआर), जिसे फाइनलाइजर्स कहा जाता है। यह C# भाषा समिति के नोट्स में परिलक्षित होता है, जो भाग में पढ़ता है: C# कंपाइलर डिस्ट्रक्टर्स को संकलित करता है ... [शायद] उदाहरण फाइनलाइज़र [एस]।[4][5] यह शब्दावली भ्रमित करने वाली है, और इस प्रकार सी # स्पेक के अधिक हाल के संस्करण भाषा-स्तरीय पद्धति को finalizers के रूप में संदर्भित करते हैं।[6]
एक अन्य भाषा जो इस शब्दावली भेद को नहीं बनाती है वह है डी। हालांकि डी कक्षाएं कचरा एकत्र की जाती हैं, उनके सफाई कार्यों को विध्वंसक कहा जाता है।[7]
प्रयोग करें
फाइनलाइजेशन का उपयोग ज्यादातर सफाई के लिए, मेमोरी या अन्य संसाधनों को जारी करने के लिए किया जाता है: मैनुअल मेमोरी प्रबंधन के माध्यम से आवंटित मेमोरी को हटाने के लिए; यदि संदर्भ गणना का उपयोग किया जाता है तो संदर्भों को स्पष्ट करने के लिए (संदर्भ संख्या में कमी); संसाधनों को जारी करने के लिए, विशेष रूप से संसाधन अधिग्रहण प्रारंभिक (आरएआईआई) मुहावरे में है; या किसी वस्तु को अपंजीकृत करने के लिए। अंतिम रूप देने की मात्रा भाषाओं के बीच महत्वपूर्ण रूप से भिन्न होती है, C++ में व्यापक अंतिमीकरण से, जिसमें मैनुअल स्मृति प्रबंधन, संदर्भ गणना, और नियतात्मक वस्तु जीवन काल होता है; जावा में अक्सर कोई अंतिम रूप नहीं दिया जाता है, जिसमें गैर-नियतात्मक वस्तु जीवनकाल होता है और अक्सर ट्रेसिंग कचरा संग्राहक के साथ लागू किया जाता है। यह भी संभव है कि कम या कोई स्पष्ट (उपयोगकर्ता-निर्दिष्ट) अंतिम रूप न हो, लेकिन संकलक, दुभाषिया, या रनटाइम द्वारा निष्पादित महत्वपूर्ण अंतर्निहित अंतिमकरण; स्वचालित संदर्भ गिनती के मामले में यह सामान्य है, जैसा कि पायथन के सीपीथॉन संदर्भ कार्यान्वयन में, या ऐप्पल के ऑब्जेक्टिव-सी के कार्यान्वयन में स्वचालित संदर्भ गणना में, जो दोनों अंतिम रूप से संदर्भों को स्वचालित रूप से तोड़ देते हैं। एक फाइनलाइज़र में मनमाना कोड शामिल हो सकता है; एक विशेष रूप से जटिल उपयोग ऑब्जेक्ट को वस्तु पूल में स्वचालित रूप से वापस करना है।
फाइनलाइजेशन के दौरान मेमोरी डीलोकेशन C++ जैसी भाषाओं में आम है जहां मैनुअल मेमोरी मैनेजमेंट मानक है, लेकिन प्रबंधित भाषाओं में भी होता है जब मेमोरी को प्रबंधित हीप के बाहर आवंटित किया गया है (बाह्य रूप से भाषा के लिए); जावा में यह जावा मूल इंटरफ़ेस (JNI) और के साथ होता है ByteBuffer
नॉन-ब्लॉकिंग I/O (जावा) में ऑब्जेक्ट | नया I/O (NIO)। यह उत्तरार्द्ध कचरा संग्रहकर्ता के इन बाहरी संसाधनों को ट्रैक करने में असमर्थ होने के कारण समस्याएँ पैदा कर सकता है, इसलिए उन्हें आक्रामक रूप से पर्याप्त रूप से एकत्र नहीं किया जाएगा, और अप्रबंधित मेमोरी को समाप्त करने के कारण आउट-ऑफ़-मेमोरी त्रुटियाँ पैदा कर सकता है - देशी मेमोरी का इलाज करके इससे बचा जा सकता है एक संसाधन के रूप में और डिस्पोजल पैटर्न का उपयोग करते हुए, जैसा कि नीचे चर्चा की गई है।
फ़ाइनलाइज़र आमतौर पर बहुत कम आवश्यक होते हैं और विध्वंसक की तुलना में बहुत कम उपयोग किए जाते हैं। वे बहुत कम आवश्यक हैं क्योंकि कचरा संग्रह स्मृति प्रबंधन को स्वचालित करता है, और बहुत कम उपयोग किया जाता है क्योंकि वे आम तौर पर निश्चित रूप से निष्पादित नहीं होते हैं - उन्हें समय पर ढंग से या बिल्कुल भी नहीं बुलाया जा सकता है, और निष्पादन वातावरण की भविष्यवाणी नहीं की जा सकती है - और इस प्रकार कोई भी क्लीनअप जो निश्चित रूप से किया जाना चाहिए, इसके बजाय किसी अन्य विधि द्वारा किया जाना चाहिए, अक्सर मैन्युअल रूप से निपटान पैटर्न के माध्यम से। विशेष रूप से, जावा और पायथन दोनों इस बात की गारंटी नहीं देते हैं कि फाइनलाइजर्स को कभी भी बुलाया जाएगा, और इस प्रकार उन्हें सफाई के लिए भरोसा नहीं किया जा सकता है।
उनके निष्पादन पर प्रोग्रामर नियंत्रण की कमी के कारण, आमतौर पर किसी भी लेकिन सबसे तुच्छ संचालन के लिए फाइनलाइज़र से बचने की सिफारिश की जाती है। विशेष रूप से, विध्वंसक में अक्सर किए जाने वाले ऑपरेशन आमतौर पर अंतिम रूप देने वालों के लिए उपयुक्त नहीं होते हैं। एक सामान्य विरोधी प्रतिमान फाइनलाइज़र लिखना है जैसे कि वे विध्वंसक थे, जो अनावश्यक और अप्रभावी दोनों हैं, अंतिम रूप देने वालों और विध्वंसकों के बीच अंतर के कारण। यह सी ++ प्रोग्रामर के बीच विशेष रूप से आम है, क्योंकि रिसोर्स एक्विजिशन इज़ इनिशियलाइज़ेशन (RAII) मुहावरे के बाद मुहावरेदार C ++ में डिस्ट्रक्टर्स का भारी उपयोग किया जाता है।
सिंटेक्स
फाइनलाइज़र का उपयोग करने जावास्क्रिप्ट (प्रोग्रामिंग भाषा) में C++/CLI, C Sharp (प्रोग्रामिंग लैंग्वेज)|C#, स्वच्छ (प्रोग्रामिंग भाषा) , जाओ (प्रोग्रामिंग भाषा) , Java (प्रोग्रामिंग लैंग्वेज), JavaScript (प्रोग्रामिंग लैंग्वेज) और Python (प्रोग्रामिंग लैंग्वेज) शामिल हैं। वाक्य-विन्यास भाषा के अनुसार काफी भिन्न होता है।
जावा में, फाइनलाइज़र एक विधि है जिसे कहा जाता है finalize
, जो ओवरराइड करता है Object.finalize
तरीका।[8]
JavaScript में, finalizationRegistry आपको किसी वस्तु के कूड़ा-कचरा एकत्र करने पर कॉलबैक का अनुरोध करने की अनुमति देता है।
पायथन में, फाइनलाइज़र एक विधि है जिसे कहा जाता है __del__
.
पर्ल में, फ़ाइनलाइज़र एक विधि है जिसे कहा जाता है DESTROY
.
सी # में, एक अंतिमकर्ता (मानक के पुराने संस्करणों में विनाशक कहा जाता है) एक विधि है जिसका नाम कक्षा का नाम है ~
पूर्वसर्ग, के रूप में ~Foo
- यह सी ++ डिस्ट्रक्टर के समान सिंटैक्स है, और इन विधियों को मूल रूप से डिस्ट्रक्टर्स कहा जाता था, अलग-अलग व्यवहार होने के बावजूद, सी ++ के साथ सादृश्य द्वारा, लेकिन इसके कारण होने वाले भ्रम के कारण इसका नाम बदलकर फाइनल कर दिया गया।[6]
सी ++/सीएलआई में, जिसमें विनाशक और फाइनलाइज़र दोनों हैं, एक विनाशक एक विधि है जिसका नाम कक्षा का नाम है ~
पूर्वसर्ग, के रूप में ~Foo
(जैसा कि सी # में), और एक फाइनलाइज़र एक विधि है जिसका नाम कक्षा का नाम है !
पूर्वसर्ग, के रूप में !Foo
.
गो फाइनलाइजर्स को कॉल करके सिंगल पॉइंटर पर लागू किया जाता है runtime.SetFinalizer
मानक पुस्तकालय में काम करता है।[9]
कार्यान्वयन
एक फाइनलाइज़र को तब कहा जाता है जब एक वस्तु (कंप्यूटर विज्ञान) कचरा एकत्र किया जाता है - एक वस्तु कचरा (पहुंच योग्य) बनने के बाद, लेकिन इससे पहले कि उसकी मेमोरी को हटा दिया जाए। कचरा संग्राहक के विवेक पर अंतिम रूप से गैर-नियतात्मक रूप से होता है, और कभी नहीं हो सकता है। यह विनाशकों के साथ विरोधाभासी है, जिन्हें नियतात्मक रूप से कहा जाता है जैसे ही कोई वस्तु अब उपयोग में नहीं होती है, और अनियंत्रित कार्यक्रम समाप्ति के मामले को छोड़कर हमेशा कहा जाता है। ऑब्जेक्ट-विशिष्ट संचालन करने की आवश्यकता के कारण फ़ाइनलाइज़र अक्सर उदाहरण विधियाँ हैं।
कचरा संग्राहक को वस्तु के पुनरुत्थान की संभावना का भी ध्यान रखना चाहिए। आमतौर पर यह पहले फाइनलाइजर्स को निष्पादित करके किया जाता है, फिर जांच की जाती है कि क्या कोई वस्तु फिर से जीवित हो गई है, और यदि ऐसा है, तो उनके विनाश को रद्द कर दिया गया है। यह अतिरिक्त जांच संभावित रूप से महंगी है - एक साधारण कार्यान्वयन सभी कचरे की फिर से जाँच करता है यदि एक भी वस्तु को अंतिम रूप दिया जाता है - और इस तरह दोनों धीमा हो जाता है और कचरा संग्रह को जटिल बना देता है। इस कारण से, फ़ाइनलाइज़र वाली वस्तुओं को फ़ाइनलाइज़र के बिना वस्तुओं की तुलना में कम बार एकत्र किया जा सकता है (केवल कुछ चक्रों पर), संसाधन लीक जैसे शीघ्र अंतिमकरण पर निर्भर होने के कारण होने वाली समस्याओं को बढ़ा देता है।
यदि किसी वस्तु को पुनर्जीवित किया जाता है, तो आगे का प्रश्न है कि क्या इसके फाइनलाइज़र को फिर से नष्ट कर दिया जाता है, जब इसे नष्ट कर दिया जाता है - विनाशकों के विपरीत, फाइनलाइज़र को संभावित रूप से कई बार बुलाया जाता है। यदि अंतिम रूप देने वालों को पुनर्जीवित वस्तुओं के लिए बुलाया जाता है, तो वस्तुएं बार-बार खुद को पुनर्जीवित कर सकती हैं और अविनाशी हो सकती हैं; यह Python 3.4 से पहले Python के CPython कार्यान्वयन में और C# जैसी CLR भाषाओं में होता है। इससे बचने के लिए, जावा, ऑब्जेक्टिव-सी (कम से कम हाल के ऐप्पल कार्यान्वयन में), और पायथन 3.4 से पायथन सहित कई भाषाओं में, वस्तुओं को एक बार में अंतिम रूप दिया जाता है, जिसके लिए ट्रैकिंग की आवश्यकता होती है यदि वस्तु को अभी तक अंतिम रूप दिया गया है।
अन्य मामलों में, विशेष रूप से सीएलआर भाषाओं जैसे सी #, अंतिम रूप से वस्तुओं से अलग से ट्रैक किया जाता है, और वस्तुओं को अंतिम रूप देने के लिए बार-बार पंजीकृत या अपंजीकृत किया जा सकता है।
समस्याएं
कार्यान्वयन के आधार पर, अंतिमकर्ता बड़ी संख्या में समस्याएं पैदा कर सकते हैं, और इस प्रकार कई अधिकारियों द्वारा दृढ़ता से हतोत्साहित किया जाता है।[10][11] इन समस्याओं में शामिल हैं:[10]* फाइनलाइजर्स को समय पर या बिल्कुल भी नहीं बुलाया जा सकता है, इसलिए उन पर राज्य को जारी रखने, दुर्लभ संसाधनों को जारी करने, या कुछ और महत्वपूर्ण करने के लिए भरोसा नहीं किया जा सकता है।
- फ़ाइनलाइज़र का परिणाम ऑब्जेक्ट पुनरुत्थान हो सकता है, जो अक्सर एक प्रोग्रामिंग त्रुटि होती है और जिसकी बहुत संभावना काफी धीमी हो जाती है और कचरा संग्रहण को जटिल बना देती है।
- फाइनलाइज़र कचरा संग्रह के आधार पर चलाए जाते हैं, जो आम तौर पर प्रबंधित मेमोरी दबाव पर आधारित होते हैं - वे अन्य संसाधनों की कमी के मामले में नहीं चलते हैं, और इस प्रकार अन्य दुर्लभ संसाधनों के प्रबंधन के लिए उपयुक्त नहीं होते हैं।
- फ़ाइनलाइज़र एक निर्दिष्ट क्रम में नहीं चलते हैं, और वर्ग अपरिवर्तनीय ्स पर भरोसा नहीं कर सकते हैं (क्योंकि वे अन्य ऑब्जेक्ट्स को संदर्भित कर सकते हैं जिन्हें पहले ही अंतिम रूप दिया जा चुका है)।
- धीमे फाइनलाइज़र अन्य फ़ाइनलाइज़र में देरी कर सकते हैं।
- फ़ाइनलाइज़र के अपवादों को आम तौर पर नियंत्रित नहीं किया जा सकता है, क्योंकि फ़ाइनलाइज़र एक अनिर्दिष्ट वातावरण में चलाया जाता है, और इसे या तो अनदेखा किया जा सकता है या अनियंत्रित प्रोग्राम समाप्ति का कारण बन सकता है।
- फ़ाइनलाइज़र प्रोग्राम इनवेरिएंट्स का उल्लंघन करते हुए लाइव ऑब्जेक्ट्स को संदर्भित और गलती से अंतिम रूप दे सकते हैं।
- फाइनलाइज़र सिंक्रनाइज़ेशन मुद्दों का कारण बन सकता है, यहां तक कि अनुक्रमिक (एकल-थ्रेडेड) कार्यक्रमों में भी, जब एक अलग धागे में अंतिम रूप दिया जाता है।[12]
- फ़ाइनलाइज़र डेडलॉक का कारण बन सकता है यदि सिंक्रोनाइज़ेशन मैकेनिज़्म जैसे ताले का उपयोग किया जाता है, एक निर्दिष्ट क्रम में नहीं चलने और संभवतः समवर्ती रूप से चलने के कारण।
- प्रोग्राम समाप्ति के दौरान चलाए जाने वाले फ़ाइनलाइज़र सामान्य रनटाइम वातावरण पर भरोसा नहीं कर सकते हैं, और इस प्रकार गलत धारणाओं के कारण विफल हो सकते हैं - इस कारण फ़ाइनलाइज़र अक्सर समाप्ति के दौरान नहीं चलते हैं।
इसके अलावा, प्रोग्रामिंग त्रुटियों के कारण या अप्रत्याशित रीचैबिलिटी के कारण कचरा होने की उम्मीद से परे पहुंच योग्य वस्तुओं के कारण अंतिम रूप से चलने में विफल हो सकते हैं। उदाहरण के लिए, जब पायथन एक अपवाद को पकड़ता है (या एक अपवाद इंटरएक्टिव मोड में नहीं पकड़ा जाता है), यह स्टैक फ्रेम का संदर्भ रखता है जहां अपवाद उठाया गया था, जो उस स्टैक फ्रेम से संदर्भित वस्तुओं को जीवित रखता है।
जावा में, एक सुपरक्लास में फ़ाइनलाइज़र एक उपवर्ग में कचरा संग्रह को धीमा कर सकता है, क्योंकि फ़ाइनलाइज़र संभावित रूप से उपवर्ग में फ़ील्ड्स को संदर्भित कर सकता है, और इस प्रकार फ़ाइनलाइज़र के चलने के बाद, अगले चक्र तक फ़ील्ड को कचरा एकत्र नहीं किया जा सकता है।[10]वंशानुक्रम पर रचना का उपयोग करके इससे बचा जा सकता है।
संसाधन प्रबंधन
संसाधनों को जारी करने के लिए फ़ाइनलाइज़र का उपयोग करने के लिए एक सामान्य एंटी-पैटर्न है, C ++ के रिसोर्स एक्विजिशन इज़ इनिशियलाइज़ेशन (RAII) मुहावरे के अनुरूप: इनिशियलाइज़र (कन्स्ट्रक्टर) में एक संसाधन प्राप्त करें, और इसे फ़ाइनलाइज़र (डिस्ट्रक्टर) में रिलीज़ करें। यह कई कारणों से काम नहीं करता है। मूल रूप से, अंतिम रूप देने वालों को कभी नहीं बुलाया जा सकता है, और यहां तक कि अगर बुलाया जाता है, तो उन्हें समय पर ढंग से नहीं बुलाया जा सकता है - इस प्रकार संसाधनों को जारी करने के लिए अंतिम रूप देने वालों का उपयोग आम तौर पर संसाधन रिसाव का कारण होगा। इसके अलावा, फाइनलाइजर्स को एक निर्धारित क्रम में नहीं बुलाया जाता है, जबकि संसाधनों को अक्सर एक विशिष्ट क्रम में जारी करने की आवश्यकता होती है, अक्सर विपरीत क्रम जिसमें वे प्राप्त किए गए थे। इसके अलावा, जैसा कि अंतिम रूप से कचरा संग्रहकर्ता के विवेक पर कहा जाता है, उन्हें अक्सर संसाधन दबाव के बावजूद प्रबंधित स्मृति दबाव (जब थोड़ी प्रबंधित स्मृति उपलब्ध होती है) के तहत बुलाया जाएगा - यदि दुर्लभ संसाधन कचरा द्वारा आयोजित किए जाते हैं लेकिन वहां बहुत कुछ है उपलब्ध प्रबंधित स्मृति की, कचरा संग्रह नहीं हो सकता है, इस प्रकार इन संसाधनों को पुनः प्राप्त नहीं किया जा सकता है।
इस प्रकार स्वचालित संसाधन प्रबंधन के लिए फाइनलाइजर्स का उपयोग करने के बजाय, कचरा-एकत्रित भाषाओं में संसाधनों को मैन्युअल रूप से प्रबंधित करना चाहिए, आम तौर पर निपटान पैटर्न का उपयोग करके। इस मामले में संसाधनों को अभी भी इनिशियलाइज़र में अधिग्रहित किया जा सकता है, जिसे स्पष्ट रूप से ऑब्जेक्ट इंस्टेंटेशन पर कहा जाता है, लेकिन निपटान विधि में जारी किया जाता है। निपटान विधि को स्पष्ट रूप से, या स्पष्ट रूप से सी # के जैसे भाषा निर्माणों द्वारा कहा जा सकता है using
, मई आपको try
-साथ-संसाधन, या पायथन with
.
हालाँकि, कुछ मामलों में संसाधनों को जारी करने के लिए डिस्पोजल पैटर्न और फ़ाइनलाइज़र दोनों का उपयोग किया जाता है। यह ज्यादातर सीएलआर भाषाओं में पाया जाता है जैसे सी #, जहां निपटान के लिए बैकअप के रूप में अंतिमकरण का उपयोग किया जाता है: जब एक संसाधन का अधिग्रहण किया जाता है, तो प्राप्त करने वाली वस्तु को अंतिम रूप देने के लिए कतारबद्ध किया जाता है ताकि संसाधन वस्तु विनाश पर जारी हो, भले ही संसाधन न हो मैनुअल निपटान द्वारा जारी किया गया।
नियतात्मक और गैर-नियतात्मक वस्तु जीवनकाल
नियतात्मक वस्तु जीवनकाल वाली भाषाओं में, विशेष रूप से C++, संसाधन प्रबंधन अक्सर संसाधन कब्जे के जीवनकाल को वस्तु जीवनकाल से बांधकर किया जाता है, आरंभीकरण के दौरान संसाधनों को प्राप्त करना और अंतिम रूप देने के दौरान उन्हें जारी करना; इसे रिसोर्स एक्विजिशन इज़ इनिशियलाइज़ेशन (RAII) के रूप में जाना जाता है। यह सुनिश्चित करता है कि संसाधन कब्ज़ा एक वर्ग अपरिवर्तनीय है, और जब वस्तु नष्ट हो जाती है तो संसाधनों को तत्काल जारी किया जाता है।
हालाँकि, गैर-नियतात्मक वस्तु जीवनकाल वाली भाषाओं में - जिसमें कचरा संग्रह वाली सभी प्रमुख भाषाएँ शामिल हैं, जैसे C#, Java, और Python - यह काम नहीं करती है, क्योंकि अंतिम रूप समय पर नहीं हो सकता है या बिल्कुल भी नहीं हो सकता है, और इस प्रकार संसाधन संसाधन रिसाव के कारण लंबे समय तक या बिल्कुल भी जारी नहीं किया जा सकता है। इन भाषाओं में संसाधनों को आम तौर पर निपटान पैटर्न के माध्यम से मैन्युअल रूप से प्रबंधित किया जाता है: संसाधन अभी भी प्रारंभ के दौरान प्राप्त किए जा सकते हैं, लेकिन कॉल करके जारी किए जाते हैं dispose
तरीका। फिर भी, इन भाषाओं में संसाधनों को जारी करने के लिए अंतिम रूप देना एक सामान्य विरोधी पैटर्न है, और कॉल करना भूल जाता है dispose
अभी भी संसाधन रिसाव का कारण बनेगा।
कुछ मामलों में दोनों तकनीकों को एक स्पष्ट निपटान पद्धति का उपयोग करके संयुक्त किया जाता है, लेकिन बैकअप के रूप में अंतिम रूप देने के दौरान किसी भी स्थिर संसाधनों को भी जारी किया जाता है। यह आमतौर पर सी # में पाया जाता है, और जब भी किसी संसाधन को प्राप्त किया जाता है, और जब भी संसाधन जारी किया जाता है, तो अंतिम रूप देने के लिए अंतिम रूप देने के लिए एक वस्तु को पंजीकृत करके कार्यान्वित किया जाता है।
वस्तु पुनरुत्थान
यदि उपयोगकर्ता द्वारा निर्दिष्ट फ़ाइनलाइज़र की अनुमति दी जाती है, तो अंतिमकरण के लिए ऑब्जेक्ट पुनरुत्थान का कारण संभव है, क्योंकि फ़ाइनलाइज़र मनमाना कोड चला सकते हैं, जो जीवित वस्तुओं से नष्ट होने वाली वस्तुओं के संदर्भ बना सकते हैं। कचरा संग्रह के बिना भाषाओं के लिए, यह एक गंभीर बग है, और झूलने वाले संदर्भों और स्मृति सुरक्षा उल्लंघनों का कारण बनता है; कचरा संग्रह वाली भाषाओं के लिए, इसे कचरा संग्रहकर्ता द्वारा रोका जाता है, आमतौर पर कचरा संग्रह में एक और कदम जोड़कर (सभी उपयोगकर्ता-निर्दिष्ट फ़ाइनलाइज़र चलाने के बाद, पुनरुत्थान की जाँच करें), जो कचरा संग्रह को जटिल और धीमा कर देता है।
इसके अलावा, वस्तु पुनरुत्थान का अर्थ है कि एक वस्तु को नष्ट नहीं किया जा सकता है, और पैथोलॉजिकल मामलों में एक वस्तु हमेशा अंतिम रूप देने के दौरान खुद को पुनर्जीवित कर सकती है, खुद को अविनाशी बना सकती है। इसे रोकने के लिए, कुछ भाषाएँ, जैसे जावा और पायथन (पायथन 3.4 से) केवल एक बार वस्तुओं को अंतिम रूप देती हैं, और पुनर्जीवित वस्तुओं को अंतिम रूप नहीं देती हैं। वस्तु-दर-वस्तु के आधार पर किसी वस्तु को अंतिम रूप दिया गया है या नहीं, यह ट्रैक करके ठोस रूप से किया जाता है। उद्देश्य-सी भी अंतिम रूप से ट्रैक करता है (कम से कम हाल ही में एप्पल संस्करण) समान कारणों से, पुनरुत्थान को बग के रूप में मानना।
.NET फ्रेमवर्क में एक अलग दृष्टिकोण का उपयोग किया जाता है, विशेष रूप से C# और विजुअल बेसिक .NET, जहां अंतिम रूप को ऑब्जेक्ट के बजाय क्यू द्वारा ट्रैक किया जाता है। इस मामले में, यदि उपयोगकर्ता द्वारा निर्दिष्ट फाइनलाइज़र प्रदान किया जाता है, तो डिफ़ॉल्ट रूप से ऑब्जेक्ट को केवल एक बार अंतिम रूप दिया जाता है (यह निर्माण पर अंतिम रूप देने के लिए कतारबद्ध होता है, और इसे अंतिम रूप देने के बाद हटा दिया जाता है), लेकिन इसे कॉल करके बदला जा सकता है GC
मापांक। कॉल करके अंतिम रूप से रोका जा सकता है GC.SuppressFinalize
, जो ऑब्जेक्ट को डीक्यू करता है, या कॉल करके पुनः सक्रिय करता है GC.ReRegisterForFinalize
, जो वस्तु को कतारबद्ध करता है। इनका विशेष रूप से उपयोग किया जाता है जब संसाधन प्रबंधन के लिए अंतिम रूप देने के लिए निपटान पैटर्न के पूरक के रूप में उपयोग किया जाता है, या ऑब्जेक्ट पूल को लागू करते समय।
इनिशियलाइज़ेशन के साथ कंट्रास्ट
अंतिम रूप देना औपचारिक रूप से आरंभीकरण (प्रोग्रामिंग) का पूरक है - आरंभीकरण जीवनकाल की शुरुआत में होता है, अंत में अंतिम रूप - लेकिन व्यवहार में महत्वपूर्ण रूप से भिन्न होता है। चर और वस्तुओं दोनों को आरंभीकृत किया जाता है, ज्यादातर मान निर्दिष्ट करने के लिए, लेकिन सामान्य तौर पर केवल वस्तुओं को अंतिम रूप दिया जाता है, और सामान्य तौर पर मूल्यों को स्पष्ट करने की कोई आवश्यकता नहीं होती है - मेमोरी को केवल ऑपरेटिंग सिस्टम द्वारा हटाया और पुनः प्राप्त किया जा सकता है।
आरंभिक मान निर्दिष्ट करने के अलावा, इनिशियलाइज़ेशन का उपयोग ज्यादातर संसाधनों को प्राप्त करने या किसी सेवा (जैसे आयोजन प्रबंधकर्ता) के साथ किसी वस्तु को पंजीकृत करने के लिए किया जाता है। इन कार्रवाइयों में सममित रिलीज या अपंजीकृत क्रियाएं होती हैं, और इन्हें फाइनलाइज़र में सममित रूप से संभाला जा सकता है, जो आरएआईआई में किया जाता है। हालांकि, कई भाषाओं में, विशेष रूप से कचरा संग्रहण वाली भाषाओं में, वस्तु का जीवनकाल असममित है: वस्तु निर्माण निश्चित रूप से कोड में कुछ स्पष्ट बिंदु पर होता है, लेकिन वस्तु विनाश गैर-नियतात्मक रूप से, कुछ अनिर्दिष्ट वातावरण में, कचरा संग्राहक के विवेक पर होता है। इस विषमता का अर्थ है कि अंतिम रूप को आरंभीकरण के पूरक के रूप में प्रभावी रूप से उपयोग नहीं किया जा सकता है, क्योंकि यह समयबद्ध तरीके से, एक निर्दिष्ट क्रम में, या एक निर्दिष्ट वातावरण में नहीं होता है। एक स्पष्ट बिंदु पर वस्तु का निपटान करके समरूपता को आंशिक रूप से बहाल किया जाता है, लेकिन इस मामले में निपटान और विनाश एक ही बिंदु पर नहीं होता है, और एक वस्तु एक निपटान में हो सकती है लेकिन अभी भी जीवित अवस्था में हो सकती है, जो वर्ग आक्रमणकारियों को कमजोर करती है और उपयोग को जटिल बनाता है।
वेरिएबल्स को आम तौर पर उनके जीवनकाल की शुरुआत में आरंभ किया जाता है, लेकिन उनके जीवनकाल के अंत में अंतिम रूप नहीं दिया जाता है - हालांकि यदि एक चर के पास इसके मूल्य के रूप में एक वस्तु है, तो वस्तु को अंतिम रूप दिया जा सकता है। कुछ मामलों में वेरिएबल्स को भी अंतिम रूप दिया जाता है: जीसीसी एक्सटेंशन वेरिएबल्स को अंतिम रूप देने की अनुमति देते हैं।
के साथ संबंध finally
जैसा कि नामकरण, अंतिम रूप और में परिलक्षित होता है finally
निर्माण दोनों समान उद्देश्यों को पूरा करते हैं: कुछ अंतिम क्रिया करना, आम तौर पर कुछ और समाप्त होने के बाद सफाई करना। जब वे घटित होते हैं तो उनमें अंतर होता है - a finally
खंड निष्पादित किया जाता है जब प्रोग्राम निष्पादन संबंधित के शरीर को छोड़ देता है try
खंड - यह स्टैक के खुलने के दौरान होता है, और इस प्रकार लंबित ढेर होता है finally
खंड, क्रम में - जबकि अंतिमकरण तब होता है जब कोई वस्तु नष्ट हो जाती है, जो स्मृति प्रबंधन पद्धति के आधार पर होती है, और सामान्य तौर पर अंतिम रूप देने की प्रतीक्षा में वस्तुओं का एक सेट होता है - अक्सर ढेर पर - जो किसी विशिष्ट क्रम में होने की आवश्यकता नहीं होती है।
हालाँकि, कुछ मामलों में ये मेल खाते हैं। सी ++ में, वस्तु विनाश नियतात्मक है, और व्यवहार a finally
किसी वस्तु के साथ उसके मूल्य के रूप में एक स्थानीय चर होने से क्लॉज का उत्पादन किया जा सकता है, जिसका दायरा एक ब्लॉक के शरीर से मेल खाता है try
खंड - वस्तु को अंतिम रूप दिया जाता है (नष्ट) जब निष्पादन इस दायरे से बाहर निकलता है, ठीक उसी तरह जैसे कि कोई था finally
खंड। इस कारण से, C++ में a नहीं है finally
निर्माण - अंतर यह है कि अंतिमकरण को कॉल साइट के बजाय विध्वंसक विधि के रूप में वर्ग परिभाषा में परिभाषित किया गया है finally
खंड।
इसके विपरीत, ए के मामले में finally
एक कोरटाइन में खंड, एक पायथन जनरेटर की तरह, कोरटाइन कभी भी समाप्त नहीं हो सकता है - केवल कभी उपज - और इस प्रकार सामान्य निष्पादन में finally
खंड कभी निष्पादित नहीं होता है। यदि कोई कोरटाइन के उदाहरणों को वस्तुओं के रूप में व्याख्या करता है, तो finally
क्लॉज को ऑब्जेक्ट का फाइनलाइज़र माना जा सकता है, और इस प्रकार इसे तब निष्पादित किया जा सकता है जब इंस्टेंस कचरा एकत्र किया जाता है। पायथन शब्दावली में, एक कोरटाइन की परिभाषा एक जनरेटर फ़ंक्शन है, जबकि इसका एक उदाहरण एक जनरेटर इटरेटर है, और इस प्रकार ए finally
जेनरेटर फ़ंक्शन में खंड इस फ़ंक्शन से तत्काल जेनरेटर इटरेटर्स में अंतिम रूप बन जाता है।
इतिहास
वस्तु विनाश की तारीखों में एक अलग कदम के रूप में अंतिम रूप देने की धारणा Montgomery (1994),[13] ऑब्जेक्ट कंस्ट्रक्शन में इनिशियलाइज़ेशन के पहले के अंतर के अनुरूप Martin & Odell (1992).[14] इस बिंदु से पहले का साहित्य इस प्रक्रिया के लिए विनाश का उपयोग करता है, अंतिम रूप देने और डीललोकेशन को अलग नहीं करता है, और इस अवधि से जुड़ी प्रोग्रामिंग भाषाएं, जैसे सी ++ और पर्ल, विनाश शब्द का उपयोग करती हैं। प्रभावशाली पुस्तक डिजाइन पैटर्न्स (1994) में अंतिम रूप देने और अंतिम रूप देने की शर्तों का भी उपयोग किया जाता है।[lower-alpha 1][15] 1995 में जावा की शुरूआत निहित थी finalize
विधियाँ, जिन्होंने इस शब्द को लोकप्रिय बनाया और इसे कचरा संग्रह से जोड़ा, और इस बिंदु से भाषाएँ आम तौर पर इस अंतर को बनाती हैं और विशेष रूप से कचरा संग्रह के संदर्भ में शब्द को अंतिम रूप देती हैं।
यह भी देखें
- कचरा संग्रह (कंप्यूटर विज्ञान), विशेष रूप से कचरा संग्रह (कंप्यूटर विज्ञान) #निर्धारणवाद पर अनुभाग
- वस्तु जीवनकाल
- इनिशियलाइज़ेशन (प्रोग्रामिंग) प्रक्रिया और संबंधित इनिशियलाइज़र पैटर्न
टिप्पणियाँ
- ↑ Published 1994, with a 1995 copyright.
संदर्भ
- ↑ Jagger, Perry & Sestoft 2007, p. 542, "In C++, a destructor is called in a determinate manner, whereas, in C#, a finalizer is not. To get determinate behavior from C#, one should use
Dispose.
- ↑ Boehm, Hans-J. (2002). विध्वंसक, अंतिम रूप देने वाले और तुल्यकालन. Symposium on Principles of Programming Languages (POPL).
- ↑ Jagger, Perry & Sestoft 2007, p. 542, C++ destructors versus C# finalizers C++ destructors are determinate in the sense that they are run at known points in time, in a known order, and from a known thread. They are thus semantically very different from C# finalizers, which are run at unknown points in time, in an unknown order, from an unknown thread, and at the discretion of the garbage collector.
- ↑ In full: "We're going to use the term "destructor" for the member which executes when an instance is reclaimed. Classes can have destructors; structs can't. Unlike in C++, a destructor cannot be called explicitly. Destruction is non-deterministic – you can't reliably know when the destructor will execute, except to say that it executes at some point after all references to the object have been released. The destructors in an inheritance chain are called in order, from most descendant to least descendant. There is no need (and no way) for the derived class to explicitly call the base destructor. The C# compiler compiles destructors to the appropriate CLR representation. For this version that probably means an instance finalizer that is distinguished in metadata. CLR may provide static finalizers in the future; we do not see any barrier to C# using static finalizers.", May 12th, 1999.
- ↑ What’s the difference between a destructor and a finalizer?, Eric Lippert, Eric Lippert’s Blog: Fabulous Adventures In Coding, 21 Jan 2010
- ↑ 6.0 6.1 Jagger, Perry & Sestoft 2007, p. 542, "In the previous version of this standard, what is now referred to as a “finalizer” was called a “destructor”. Experience has shown that the term “destructor” caused confusion and often resulted in incorrect expectations, especially to programmers knowing C++. In C++, a destructor is called in a determinate manner, whereas, in C#, a finalizer is not. To get determinate behavior from C#, one should use
Dispose.
" - ↑ Class destructors Class destructors in D
- ↑ java.lang, क्लास ऑब्जेक्ट: finalize() finalize
- ↑ "Runtime package - runtime - PKG.go.dev".
- ↑ 10.0 10.1 10.2 "MET12-J. Do not use finalizers", Dhruv Mohindra, The CERT Oracle Secure Coding Standard for Java, 05. Methods (MET) Archived 2014-05-04 at the Wayback Machine
- ↑ object.__del__(self), The Python Language Reference, 3. Data model: "...
__del__()
methods should do the absolute minimum needed to maintain external invariants." - ↑ Hans-J. Boehm, Finalization, Threads, and the Java™ Technology-Based Memory Model, JavaOne Conference, 2005.
- ↑ Montgomery 1994, p. 120, "As with object instantiation, design for object termination can benefit from implementation of two operations for each class—a finalize and a terminate operation. A finalize operation breaks associations with other objects, ensuring data structure integrity."
- ↑ Montgomery 1994, p. 119, "Consider implementing class instantiation as a create and initialize operation, as suggested by Martin and Odell. The first allocates storage for new objects, and the second constructs the object to adhere to specifications and constraints."
- ↑ "Every new class has a fixed implementation overhead (initialization, finalization, etc.).", "destructor In C++, an operation that is automatically invoked to finalize an object that is about to be deleted."
अग्रिम पठन
- Jagger, Jon; Perry, Nigel; Sestoft, Peter (2007). Annotated C# Standard. Morgan Kaufmann. ISBN 978-0-12-372511-0.
- Martin, James; Odell, James J. (1992). Object-oriented analysis and design. Prentice-Hall. ISBN 978-0-13-630245-2.
- Montgomery, Stephen (January 24, 1994). Object-Oriented Information Engineering: Analysis, Design, and Implementation. Academic Press. ISBN 978-0-12-505040-1.
बाहरी संबंध
- "Finalize Instead Of Proper Destructor", WikiWikiWeb – comparison of Java finalizers with C++ destructors
- Paul Krill, "Oracle recommends axing Java object finalizer", JavaWorld Mar 29, 2017.