2012-12-20 12 views
17

जैसे ही मैं उच्च स्तर की ऑब्जेक्ट-उन्मुख भाषा की तरह जावास्क्रिप्ट का अधिक उपयोग करता हूं, मुझे लगता है कि मैं सी/सी ++ प्रोग्रामर की तरह सोच रहा हूं कि जब मैं ऑब्जेक्ट्स के साथ समाप्त होता हूं। मुझे पता है कि जीसी अंततः दौड़ने जा रही है और मेरी गड़बड़ी को साफ कर रही है, लेकिन क्या ऐसी चीजें हैं जो मैं वास्तव में इसके साथ मदद करने के लिए कर सकता हूं?क्या जावास्क्रिप्ट कचरा कलेक्टर की सहायता करने के लिए यह समझ में आता है?

उदाहरण के लिए, मेरे पास बड़ी/जटिल प्राथमिक वस्तुओं की एक श्रृंखला है ... प्रत्येक प्राथमिक वस्तु में सरणी और अन्य सहायक वस्तु संदर्भ अंदर हो सकते हैं। यदि मुझे प्राथमिक ऑब्जेक्ट के साथ किया गया है और इसे सरणी से हटा दें, तो जीसी संभावित रूप से आखिरकार अन्य सभी चीजों को समझ लेगा जो ऑब्जेक्ट सभी को स्वयं, सर्कुलर आंतरिक संदर्भ और सभी को इंगित करता है। लेकिन क्या यह समझ में आता है कि भंडारण सरणी से प्राथमिक ऑब्जेक्ट को इसके माध्यम से जाने के लिए और array.length = 0 किसी भी सरणी और संदर्भ = मूल रूप से जीसी नौकरी को आसान बनाने के लिए किसी भी ऑब्जेक्ट को हटा दें (उदाहरण के लिए संदर्भों को स्पष्ट रूप से निकालना जीसी के लिए कम है धावन पथ)? यदि आप करेंगे तो एक मैनुअल विनाशक की तरह। क्या ऐसा करने के लायक है या मैं कम/कोई लाभ के लिए समय/प्रयास बर्बाद कर रहा हूं?

मुझे लगता है कि यह जीसी प्रश्न (जावा इत्यादि) का एक सामान्य सिद्धांत है, लेकिन मैं मुख्य रूप से इस प्रश्न के प्रयोजनों के लिए जावास्क्रिप्ट में रूचि रखता हूं।

धन्यवाद!

+3

मुझे विश्वास नहीं है कि कोई दिलचस्प/उपयोगी/बेवकूफ सवाल नहीं आया है। +1। –

+0

मुझे यह उत्तर बहुत दिलचस्प लगता है: http://stackoverflow.com/a/4324162/752527 –

उत्तर

4

यह विशिष्ट कचरा कलेक्टर पर निर्भर हो सकता है, इसलिए एक उत्तर इस बात पर निर्भर करेगा कि आप किस जावास्क्रिप्ट इंजन का उपयोग कर रहे हैं।

सबसे पहले, मुझे लगता है कि सबसे अच्छा एप्लिकेशन कोड दो चीजें करता है। यह कार्यक्षमता और प्रदर्शन के अपने तकनीकी लक्ष्यों को प्राप्त करता है, और यह बदलने के लिए लचीला है। अतिरिक्त कोड को अतिरिक्त जटिलता को न्यायसंगत बनाने के लिए पर्याप्त उद्देश्य प्रदान करना चाहिए।

इसी के साथ

कहा, Google's notes on V8, जो Chrome द्वारा उपयोग JavaScript इंजन है,

के अनुसार अब एक प्रक्रिया कचरा संग्रहण के रूप में जाना आवश्यक हैं कि वस्तुओं के द्वारा प्रयोग किया स्मृति वी 8 reclaims। तेजी से ऑब्जेक्ट आवंटन सुनिश्चित करने के लिए, शॉर्ट कचरा संग्रहण विराम, और कोई स्मृति विखंडन V8 एक स्टॉप-द-वर्ल्ड, जेनरेशनल, सटीक, कचरा कलेक्टर नियोजित करता है। इसका मतलब है कि वी 8:

  • कचरा संग्रहण चक्र करते समय प्रोग्राम निष्पादन रोकता है।
  • अधिकांश कचरा संग्रहण चक्रों में ऑब्जेक्ट ढेर का केवल एक हिस्सा संसाधित करता है। यह एप्लिकेशन को रोकने के प्रभाव को कम करता है।
  • हमेशा जानता है कि सभी ऑब्जेक्ट्स और पॉइंटर्स स्मृति में कहां हैं। यह पॉइंटर्स के रूप में गलत रूप से पहचानने वाली वस्तुओं से बचाता है जो स्मृति लीक में परिणाम दे सकते हैं।

वी 8 में, वस्तु ढेर को दो भागों में खंडित किया जाता है: नई जगह है जहाँ ऑब्जेक्ट का निर्माण होगा, और पुराने अंतरिक्ष के लिए जो एक कचरा संग्रहण चक्र जीवित वस्तुओं को बढ़ावा दिया जाता है। यदि किसी ऑब्जेक्ट को कचरा संग्रहण चक्र में स्थानांतरित किया गया है, तो V8 ऑब्जेक्ट पर सभी पॉइंटर्स अपडेट करता है।

पीढ़ी के कचरे के संग्राहक ढेर के बीच वस्तुओं को स्थानांतरित करते हैं, जहां सभी जीवित वस्तुओं को एक गंतव्य ढेर में स्थानांतरित किया जाता है। गंतव्य पर स्थानांतरित नहीं किया गया कुछ भी कचरा माना जाता है। यह स्पष्ट नहीं है कि वी 8 कचरा कलेक्टर लाइव ऑब्जेक्ट्स की पहचान कैसे करता है, लेकिन हम सुराग के लिए कुछ अन्य जीसी कार्यान्वयन देख सकते हैं।

एक अच्छी तरह से प्रलेखित जीसी कार्यान्वयन के व्यवहार का एक उदाहरण के रूप में, जावा के समवर्ती मार्क-स्वीप कलेक्टर:

  1. आवेदन रोकता है।
  2. एप्लिकेशन कोड से पहुंचने योग्य वस्तुओं की एक सूची बनाता है।
  3. एप्लिकेशन को फिर से शुरू करता है। समानांतर में, सीएमएस कलेक्टर एक "चिह्न" चरण चलाता है, जिसमें यह पारगमनशील पहुंच योग्य वस्तुओं को "कचरा नहीं" के रूप में चिह्नित करता है। चूंकि यह प्रोग्राम निष्पादन के साथ समानांतर है, यह एप्लिकेशन द्वारा किए गए संदर्भ परिवर्तनों को भी ट्रैक करता है।
  4. एप्लिकेशन को रोकता है।
  5. नई पहुंच योग्य वस्तुओं को चिह्नित करने के लिए एक दूसरा ("टिप्पणी") चरण चलाता है।
  6. एप्लिकेशन को फिर से शुरू करता है। समानांतर में, यह सभी वस्तुओं को कचरा के रूप में पहचाना जाता है और ढेर ब्लॉक को पुनः प्राप्त करता है।

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

कुछ अच्छा है, अगर जावा कचरा संग्रह http://www.oracle.com/technetwork/java/javase/memorymanagement-whitepaper-150215.pdf पर काम करता है तो कुछ अच्छा है। कचरा संग्रह जावा के लिए अद्वितीय नहीं है, इसलिए मुझे जावा आभासी मशीनों और जावास्क्रिप्ट इंजन जैसे अन्य रनटाइम द्वारा उठाए गए विभिन्न दृष्टिकोणों के बीच कुछ समानता पर संदेह होगा।

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

तो ऐसी स्थिति में जहां ओएस ने कुछ ब्लॉकों को बदल दिया हो, कचरा कलेक्टर "विशेष रूप से लंबे समय तक रहने वाली वस्तुओं पर" सहायता करने का कार्य, धीमा चीजों को धीमा कर सकता है।

और यदि आप स्वैपिंग के बारे में चिंतित होने के लिए पर्याप्त डेटा नहीं बना रहे हैं, तो उचित कचरा कलेक्टर को नोटिस करने में काफी समय नहीं लगेगा।

तो संभावना है कि यह प्रयास के लायक नहीं है, और प्रतिकूल हो सकता है। हालांकि यह संभवतः ढेर "प्रभुत्व" के संदर्भ को छोड़ने के लिए समझ में आता है। ये वे वस्तुएं हैं जो एकत्र की जाती हैं, कई अन्य वस्तुओं के संग्रह की अनुमति देगी। तो संग्रह को संदर्भ में छोड़ दें, लेकिन संग्रह के भीतर प्रत्येक आइटम को नहीं।

+1

दिलचस्प, धन्यवाद। यह पाठ्यक्रम के कार्यान्वयन पर निर्भर करता है, लेकिन यह हिस्सा एक महत्वपूर्ण ले-दूर हो सकता है: "चूंकि डिस्कनेक्ट की गई वस्तुओं को सुलभ नहीं किया जा सकता है, इसलिए अन्य डिस्कनेक्ट की गई वस्तुओं से उनकी जुड़ाव खेल में नहीं आनी चाहिए" – mark

+0

यदि कोई संदर्भ किसी के लिए जीवित रहने वाला नहीं है किसी ऑब्जेक्ट ग्राफ़ का हिस्सा, आंतरिक संदर्भों को तोड़ने के लिए ग्राफ़ को चलाना प्रयास की बर्बादी होगी। ऐसे मामलों में जहां संदर्भ ग्राफ के बड़े हिस्से उपयोगी हो जाते हैं लेकिन कुछ छोटे हिस्से अभी भी उपयोगी हो सकते हैं और उनके पास लक्ष्यीकरण के संदर्भ हो सकते हैं, ग्राफ के बेकार हिस्सों के संदर्भों को नष्ट करना अनिवार्य बढ़ते स्मृति उपयोग को रोकने के लिए आवश्यक हो सकता है। – supercat

+0

सहमत हैं, ऐसे मामलों में जहां आप मूल वस्तु को संग्रह के योग्य होने की अपेक्षा नहीं कर रहे हैं, फिर भी जब आप जानते हैं कि उन्हें अब आवश्यकता नहीं है तो व्यक्तिगत संदर्भों को त्यागना अभी भी समझ में आता है। – GargantuChet

3

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

कचरा संग्रहण आप के लिए एक प्रमुख लागत होता जा रहा है, तो आप की संभावना से बेहतर कर रहे हैं वस्तुओं है कि कचरा एकत्र होने के लिए की संख्या कम करने पर ध्यान केंद्रित कर (Object Pool Pattern पर विचार करें)

5

शायद ही कभी।

जो कभी भी अलग नहीं है।

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

  • आप साबित करने के लिए अपने आप को विश्लेषण उपकरणों से कठिन नंबर के साथ एक वास्तविक जरूरत नहीं है कि है, और
  • आप की असली समझ का प्रदर्शन कर सकते हैं क्या वास्तव में कचरा कलेक्टर की मदद के लिए क्रम में को बदलने की आवश्यकता है।

इनमें से कोई भी हासिल करना आसान नहीं है।

तो शायद सबसे अच्छा जवाब यह है कि जब तक कि आप अपवादों को समझने के लिए पहले से ही उन्नत नहीं हो जाते हैं, तो आपको शायद इसके बारे में चिंता न करें।

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