2012-10-03 42 views
10

मेरी समझ के अनुसार, दोनों उदाहरण विधियों और स्थिर तरीकों का सीएलआर कंपाइलर द्वारा समान व्यवहार किया जाता है और जब भी पहली बार विधि कहा जाता है तो आईएल कोड JITted होता है। आज मैंने अपने सहयोगी के साथ चर्चा की और उसने मुझे बताया कि स्थिर तरीकों का उदाहरण उदाहरण विधियों के समान नहीं माना जाता है। यानी स्टेटिक पद्धतियां जैसे ही असेंबली को एप्लिकेशन डोमेन में लोड किया जाता है, वहीं इंस्टीट्यूट विधियां जेआईटीटी होती हैं क्योंकि उन्हें पहली बार बुलाया जाता है।क्या स्थिर तरीके उत्सुकता से संकलित (JIT'ed) हैं?

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

कृपया इस व्यवहार को समझने में मेरी मदद करें।

+0

मुझे लगता है कि होगा कि वे जैसे ही _type_ पहले भरी हुई है jitted किया है (रिकॉर्ड के लिए इस .NET 4.5 पर किया गया था)। यह तब होता है जब असेंबली लोड होती है। – Oded

+0

क्या आपके सहयोगी के पास इसका संदर्भ है? शायद यह व्यवहार भी बताता है। अन्यथा आप किसी से यह बताने के लिए कह रहे हैं कि ऐसा कुछ क्यों हो रहा है जो हो रहा है। "12 अलग-अलग इलाज नहीं" के लिए – millimoose

उत्तर

10

WinDbg/SOS का उपयोग करके जेआईटी संकलित किए जाने के तरीकों को देखते हुए देखते हैं कि उन्हें कॉल करने से पहले स्थैतिक विधियों को संकलित नहीं किया जाता है।

class SomeType 
{ 
    [MethodImpl(MethodImplOptions.NoInlining)] 
    public void InstanceMethod() 
    { 
     Console.WriteLine("instance"); 
    } 

    [MethodImpl(MethodImplOptions.NoInlining)] 
    public static void TypeMethod() 
    { 
     Console.WriteLine("type"); 
    } 
} 

मैं NoInlining विकल्प का उपयोग एक रिलीज के निर्माण में इन तरीकों को इनलाइन से संकलक को रोकने के लिए:

निम्नलिखित वर्ग पर विचार करें।

यदि मैं नीचे एक छोटा ऐप चलाता हूं और WinDbg संलग्न करता हूं तो मैं देख सकता हूं कि विधियों को जेआईटी संकलित क्यों किया जाता है।

var st = new SomeType(); 

Console.WriteLine("attach"); 
Console.ReadLine(); 

Console.WriteLine("calling methods"); 
st.InstanceMethod(); 
SomeType.TypeMethod(); 

Console.ReadLine(); 

SomeType के लिए विधि तालिका संलग्न की बिंदु पर इस तरह दिखता है:

0:004> !dumpmt -md 0041387c 
EEClass:   004114d4 
Module:   00412e94 
Name:   ConsoleApplication2.SomeType 
mdToken:   02000007 
File:    c:\temp\ConsoleApplication1\ConsoleApplication1\bin\Release\ConsoleApplication1.exe 
BaseSize:  0xc 
ComponentSize: 0x0 
Slots in VTable: 7 
Number of IFaces in IFaceMap: 0 
-------------------------------------- 
MethodDesc Table 
    Entry MethodDe JIT Name 
6d374960 6d076728 PreJIT System.Object.ToString() 
6d368790 6d076730 PreJIT System.Object.Equals(System.Object) 
6d368360 6d076750 PreJIT System.Object.GetHashCode() 
6d3616f0 6d076764 PreJIT System.Object.Finalize() 
0041c035 00413874 NONE ConsoleApplication2.SomeType..ctor() 
0041c02d 0041385c NONE ConsoleApplication2.SomeType.InstanceMethod() 
0041c031 00413868 NONE ConsoleApplication2.SomeType.TypeMethod() 

तरीकों के बाद स्पष्ट रूप से किया गया है यह इस तरह दिखता है अनुरोध किया गया:

0:007> !dumpmt -md 0041387c 
EEClass:   004114d4 
Module:   00412e94 
Name:   ConsoleApplication2.SomeType 
mdToken:   02000007 
File:   c:\temp\ConsoleApplication1\ConsoleApplication1\bin\Release\ConsoleApplication1.exe 
BaseSize:  0xc 
ComponentSize: 0x0 
Slots in VTable: 7 
Number of IFaces in IFaceMap: 0 
-------------------------------------- 
MethodDesc Table 
    Entry MethodDe JIT Name 
6d374960 6d076728 PreJIT System.Object.ToString() 
6d368790 6d076730 PreJIT System.Object.Equals(System.Object) 
6d368360 6d076750 PreJIT System.Object.GetHashCode() 
6d3616f0 6d076764 PreJIT System.Object.Finalize() 
0041c035 00413874 NONE ConsoleApplication2.SomeType..ctor() 
004700e0 0041385c JIT ConsoleApplication2.SomeType.InstanceMethod() 
00470110 00413868 JIT ConsoleApplication2.SomeType.TypeMethod() 

अर्थात तरीकों को जेआईटी संकलित नहीं किया जाता है जब तक वे वास्तव में नहीं आते हैं।

+0

मुझे लगता है कि यह बहुत अच्छी तरह से बताता है कि कैसे और कब विधियां मिल रही हैं। मैं अपने सहयोगी के साथ इस क्यू एंड ए के लिंक साझा करूंगा। आपकी मदद के लिए बहुत बहुत शुक्रिया। – jags

+0

अच्छा अन्वेषण उत्तर। उपयोग किए गए सीएलआर/.NET संस्करणों को जोड़ने पर विचार करें, हालांकि - भविष्य में यह परिवर्तन होने पर (या हमेशा वही नहीं होता है)। –

1

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

अद्यतन के लिए 4.0 (इशारा कर के लिए धन्यवाद @JulienLebosquain)

.NET 4.0 एक तथाकथित लेज़ी प्रकार प्रारंभ, कि मूल रूप से व्यवहार और स्टैटिक्स निर्माता को बदलने का उपयोग करता है कहा जाता है जब के रूप में जल्द ही एक स्थिर क्षेत्र पहली बार acceded है।

+3

+1; स्थिर रचनाकारों के बारे में, यह अब सत्य नहीं है, कृपया http://msmvps.com/blogs/jon_skeet/archive/2010/01/26/type-initialization-changes-in-net-4-0 देखें।एएसपीएक्स –