कचरा उठाने वाला यहां अनंत लूप से कैसे बचता है?


101

निम्नलिखित सी # कार्यक्रम पर विचार करें, मैंने इसे कोडगुल्फ़ पर लूपिंग के बिना एक लूप बनाने के उत्तर के रूप में प्रस्तुत किया:

class P{
    static int x=0;
    ~P(){
        System.Console.WriteLine(++x);
        new P();
    }
    static void Main(){
        new P();
    }
}

यह कार्यक्रम मेरे निरीक्षण में एक अनंत लूप की तरह दिखता है, लेकिन यह कई हज़ार पुनरावृत्तियों के लिए चलता है, और फिर प्रोग्राम बिना त्रुटि के सफलतापूर्वक समाप्त हो जाता है (कोई त्रुटि नहीं फेंकी जाती है)। क्या यह एक विशेष उल्लंघन है कि Pअंततः अंतिम रूप देने वाले को नहीं कहा जाता है?

स्पष्ट रूप से यह बेवकूफ कोड है, जिसे कभी भी प्रकट नहीं होना चाहिए, लेकिन मुझे इस बात की उत्सुकता है कि कार्यक्रम कभी पूरा कैसे हो सकता है।

मूल कोड गोल्फ पोस्ट :: /codegolf/33196/loop-without-looping/33218#33218


49
मैं इसे चलाने से डरता हूं।
एरिक श्रेरर

6
यह कहा जाता है कि अंतिम रूप से मान्य व्यवहार के दायरे में नहीं है । मैं नहीं जानता कि क्यों यह कई हजार पुनरावृत्तियों को चलाने के लिए परेशान करता है, मैं शून्य आह्वान की अपेक्षा करता हूं।

27
सीएलआर को फाइनल थ्रेड से सुरक्षा मिलती है जो कभी भी अपना काम पूरा नहीं कर पाती है। यह 2 सेकंड के बाद इसे जबरदस्ती समाप्त कर देता है।
हंस पासंट

2
इसलिए शीर्षक में आपके प्रश्न का वास्तविक उत्तर यह है कि यह केवल 40 सेकंड के लिए अनंत लूप को चलाने से बचता है और फिर इसे समाप्त कर दिया जाता है।
लेज़ वी। कार्लसन 19

4
इसे आज़माने से, ऐसा लगता है कि यह कार्यक्रम 2 सेकंड के बाद ही सब कुछ मार देता है, चाहे जो भी हो। वास्तव में यदि आप थ्रेड्स को थूकते रहते हैं तो यह काफी लंबा चलता है :)
माइकल बी

जवाबों:


110

C # के माध्यम से CLR के दूसरे संस्करण में रिक्टर के अनुसार (हां मुझे अपडेट करने की आवश्यकता है):

पृष्ठ ४। Page

के लिए (सीएलआर बंद हो रहा है) प्रत्येक अंतिम विधि को वापस लौटने के लिए लगभग दो सेकंड दिए गए हैं। यदि एक अंतिम विधि दो सेकंड के भीतर वापस नहीं आती है, तो सीएलआर सिर्फ प्रक्रिया को मारता है - कोई और अंतिम तरीका नहीं कहा जाता है। साथ ही, यदि सभी ऑब्जेक्ट्स को अंतिम रूप देने के लिए 40 सेकंड से अधिक समय लगता है, तो फिर से, CLR प्रक्रिया को मार देता है।

इसके अलावा, जैसा कि सर्व का उल्लेख है, इसके अपने धागे हैं।


5
इस कोड में प्रत्येक अंतिम विधि 40 सेकंड प्रति ऑब्जेक्ट के तहत नाटकीय रूप से होती है। कि एक नई वस्तु बनाई गई है और फिर अंतिम रूप देने के लिए पात्र वर्तमान फाइनल के लिए प्रासंगिक नहीं है।
जैकब क्रॉल

2
यह वास्तव में क्या काम हो जाता है नहीं है। बंद होने पर खाली होने वाली कतार पर एक समय समाप्त होता है। यह कोड किस पर विफल होता है, यह उस कतार में नई वस्तुओं को जोड़ता रहता है।
हंस पैसेंट

बस इस बारे में सोचकर, "", अगर यह अधिक समय लेता है, तो सभी ऑब्जेक्ट्स को अंतिम रूप देने के लिए 40 सेकंड से अधिक समय लगता है, फिर से, CLR प्रक्रिया को मारता है। "
एरिक श्रेरर

23

अंतिम धागा मुख्य धागे में नहीं चलता है। फाइनल करने वाले के पास अपना स्वयं का धागा होता है जो कोड चलाता है, और यह एक अग्रभूमि धागा नहीं है जो एप्लिकेशन को चालू रखेगा। मुख्य धागा प्रभावी रूप से तुरंत पूरा होता है, जिस बिंदु पर अंतिम धागा बस उतनी बार चलता है जितना कि प्रक्रिया को फाड़ने से पहले मौका मिलता है। कुछ भी नहीं कार्यक्रम को जीवित रखा जा रहा है।


यदि फाइनल के 40 सेकंड पूरे नहीं हुए हैं तो प्रोग्राम को कोई मुख्य धागा जीवित नहीं होने के कारण बाहर निकल जाना चाहिए, इसे समाप्त कर दिया जाएगा और प्रक्रिया समाप्त हो जाएगी। ये पुराने मूल्य हैं, हालांकि Microsoft ने अब तक वास्तविक संख्याओं या पूरे एल्गोरिथ्म को भी ट्विस्ट किया होगा। Se blog.stephencleary.com/2009/08/finalizers-at-process-exit.html
Lasse V. Karlsen

@ LasseV.Karlsen भाषा का वह दस्तावेज व्यवहार है, या एमएस ने कार्यान्वयन के विवरण के रूप में अपने अंतिम रूप को लागू करने के लिए कैसे चुना है? मुझे बाद की उम्मीद होगी।
सेवित

मैं बाद की भी उम्मीद करता हूं। इस व्यवहार का सबसे आधिकारिक संदर्भ मैंने देखा है कि एरिक ने अपने उत्तर में जेफरी रिक्टर द्वारा सी # के माध्यम से पुस्तक # से पोस्ट किया है।
लास वी। कार्लसन जू

8

कचरा उठाने वाला एक सक्रिय सिस्टम नहीं है। यह "कभी-कभी" चलता है और ज्यादातर मांग पर (उदाहरण के लिए जब ओएस द्वारा पेश किए गए सभी पृष्ठ भरे हुए हैं)।

अधिकांश कचरा संग्राहक सब-वे में ब्रेड-प्रथम पीढ़ी की तरह तरीके से चलते हैं। अधिकांश मामलों में ऑब्जेक्ट के पुनर्नवीनीकरण से पहले घंटे लग सकते हैं।

केवल समस्या तब होती है जब आप प्रोग्राम को समाप्त करना चाहते हैं। हालाँकि यह वास्तव में कोई समस्या नहीं है। जब आप killएक OS का उपयोग करते हैं तो प्रक्रियाओं को समाप्त करने के लिए विनम्रता से पूछेंगे। जब प्रक्रिया हालांकि सक्रिय रहती है, तो कोई उपयोग कर सकता है kill -9जहां ऑपरेटिंग सिस्टम सभी नियंत्रण को हटा देता है।

जब मैंने इंटरैक्टिव csharpवातावरण में आपका कोड चलाया , तो मुझे मिल गया है:

csharp>  

1
2

Unhandled Exception:
System.NotSupportedException: Stream does not support writing
  at System.IO.FileStream.Write (System.Byte[] array, Int32 offset, Int32 count) [0x00000] in <filename unknown>:0 
  at System.IO.StreamWriter.FlushBytes () [0x00000] in <filename unknown>:0 
  at System.IO.StreamWriter.FlushCore () [0x00000] in <filename unknown>:0 
  at System.IO.StreamWriter.Write (System.Char[] buffer, Int32 index, Int32 count) [0x00000] in <filename unknown>:0 
  at System.IO.CStreamWriter.Write (System.Char[] buffer, Int32 index, Int32 count) [0x00000] in <filename unknown>:0 
  at System.IO.CStreamWriter.Write (System.Char[] val) [0x00000] in <filename unknown>:0 
  at System.IO.CStreamWriter.Write (System.String val) [0x00000] in <filename unknown>:0 
  at System.IO.TextWriter.Write (Int32 value) [0x00000] in <filename unknown>:0 
  at System.IO.TextWriter.WriteLine (Int32 value) [0x00000] in <filename unknown>:0 
  at System.IO.SynchronizedWriter.WriteLine (Int32 value) [0x00000] in <filename unknown>:0 
  at System.Console.WriteLine (Int32 value) [0x00000] in <filename unknown>:0 
  at P.Finalize () [0x00000] in <filename unknown>:0

इस प्रकार आपका प्रोग्राम क्रैश हो stdoutजाता है क्योंकि पर्यावरण की समाप्ति से अवरुद्ध है।

जब हटाने Console.WriteLineऔर कार्यक्रम को मार रहा है। यह पांच सेकंड के बाद कार्यक्रम समाप्त हो जाता है (दूसरे शब्दों में, कचरा कलेक्टर को छोड़ देता है और बस फाइनल में खाते में लेने के बिना सभी मेमोरी को मुक्त कर देगा)।


यह दिलचस्प है कि इंटरएक्टिव सीएसएचआरपी पूरी तरह से अलग कारणों से चल रहा है। मूल कार्यक्रम स्निपेट में कंसोल रिटलाइन नहीं थी, मैं उत्सुक हूं अगर यह भी समाप्त हो जाएगा।
माइकल बी

@ मिचेल बी: मैंने इसका परीक्षण किया है (नीचे टिप्पणी देखें)। यह पांच सेकंड के लिए इंतजार करता है और फिर समाप्त हो जाता है। मुझे लगता है कि पहले Pउदाहरण के फाइनल केवल समय समाप्त हो गया है।
विलेम वैन ओन्सेम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.