2009-08-24 17 views
7

यहां बहुत से लोग उलझन में हैं,सीएलआर स्थिर वर्ग कहां स्टोर करता है?

सामान्य वर्ग ढेर में अपना डेटा संग्रहीत करता है? और ढेर के लिए संदर्भ (सूचक)।

जब ढेर गुंजाइश से बाहर हो जाते हैं, अगली बार कचरा कलेक्टर किक से स्मृति को हटा देता है और हटा देता है।

अब स्थिर कक्षाओं के मामले में, स्मृति कचरा कलेक्टर द्वारा साफ नहीं किया जा सकता है क्योंकि इसे पूरा कार्यक्रम होना चाहिए। और संदर्भ में पहली जगह पाने का कोई तरीका नहीं है।

तो जब हम कंसोल कहते हैं। उदाहरण के लिए लिखें? कार्यक्रम कहां से संदर्भ प्राप्त करता है (यह स्थैतिक वर्ग के संदर्भ को कहां संग्रहीत करता है)? या यह सिर्फ इसे सीधे कॉल करता है, लेकिन कैसे?

+4

मुझे इस प्रश्न के किसी भी हिस्से को समझ में नहीं आता है। "इसका मूल्य" और "इसके रेफरी" से आपका क्या मतलब है? –

+0

मुझे उम्मीद है कि वह डेटा सदस्यों से निष्पादन योग्य कोड को अलग करने के तरीके के बारे में बात कर रहा है। –

+1

अन्य मुद्दों के अलावा, यह "इसकी" है। – jason

उत्तर

16

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

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

उदाहरण के लिए, इस कोड को देखो:

class ObjectWrapper 
{ 
    Object obj = new Object(); 
} 

static void Main(string[] args) 
{ 
    ObjectWrapper wrapper = new ObjectWrapper(); 
    ... 
} 

मुख्य विधि एक ObjectWrapper वर्ग का एक उदाहरण बनाता है। यह उदाहरण ढेर पर रहता है।

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

class Singleton 
{ 
    static readonly instance = new Singleton(); 
} 

सिंगलटन वस्तु का उदाहरण ढेर पर रहता है,:

अब, यह निम्न कोड को की तुलना करें। हालांकि, संदर्भ एक स्थिर संदर्भ है। यह वैश्विक या "रूट" संदर्भों की सूची में सीएलआर द्वारा बनाए रखा जाता है।

अब इस स्थिर वर्ग को देखो:

class ObjectWrapper 
{ 
    Object obj = new Object(); 
} 

static class HelperMethods 
{ 
    static int DoSomethingUseful(ObjectWrapper wrapper1) 
    { 
     ObjectWraper wrapper2 = wrapper1; 
     // code here 
    } 
} 

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

+0

+1, विवरण का आनंद लिया। – user7116

+0

जहां तक ​​"जड़ें" जाती हैं, इस आलेख को देखें जो .NET के जीसी एल्गोरिदम बताती है और स्पष्ट करती है कि जीसी में जड़ें कैसे भूमिका निभाती हैं। http://msdn.microsoft.com/en-us/magazine/bb985010.aspx – felideon

+0

इस उत्तर में कई बिंदु हैं जो पूरी तरह सटीक नहीं हैं। एक के लिए, कथन 'कहीं भी नहीं है "संदर्भ" कहीं भी "गलत है। प्रत्येक प्रकार, स्थिर या अन्यथा का संदर्भ लोडर ढेर पर होता है। पूरे प्रकार की प्रणाली को लोडर ढेर पर प्रबंधित किया जाता है, जिसमें प्रकार और उनके सदस्यों के संदर्भ होते हैं। साथ ही, 'यह वर्ग कभी भी ढेर पर स्मृति का उपभोग नहीं करेगा' भी गलत है ... जबकि यह जीसी ढेर अंतरिक्ष का उपभोग नहीं करता है, यह लोडर ढेर पर ढेर स्थान का उपभोग करता है। एक सूचक का संदर्भ केवल सूचक होने का विचार भी गलत है ... सीएलआर संकेत के कई स्तरों का उपयोग करता है। – jrista

6

आपको एक साधारण उत्तर देने के लिए, स्थिर वर्ग लोडर हीप कहलाते हैं "संग्रहीत" होते हैं।लोडर ढेर विशेष, गैर-जीसी उपचार होते हैं जिनकी अत्यधिक अनुमानित और सख्त वृद्धि दर होती है। जब एक .NET अनुप्रयोग शुरू होता है, तो कई ऐपडोमेन वास्तव में बनाए जाते हैं। प्राथमिक ऐप डोमेन के अतिरिक्त, सिस्टम और साझा ऐप डोमेन हैं जिनमें सिस्टम नेमस्पेस और mscorelib, विशेष ढेर (जैसे लोडर ढेर) और सीएलआर स्वयं शामिल हैं।

एक पूरी तरह से विस्तृत विवरण के लिए, निम्न MSDN पत्रिका लेख पढ़ें: पहले कुछ साल से होने के बावजूद

Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects

, यह अभी भी लागू होता है। (हालांकि, मैं यह नहीं कह सकता कि .NET 4.0 ने इसे बहुत बदल दिया है।)

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