2010-04-11 9 views
5

यह मेरी समझ है कि सभी .NET ऑब्जेक्ट इंस्टेंस 8 बाइट 'ऑब्जेक्ट हेडर' से शुरू होते हैं: एक सिंच ब्लॉक (एक सिंचटेबल एंटर्री टेबल में 4 बाइट पॉइंटर), और एक प्रकार हैंडल (4 बाइट पॉइंटर प्रकार विधि तालिका में)।ऑब्जेक्ट लेआउट में सिंक ब्लॉक नहीं देख रहा

मैं इसे वीएस 2010 आरसी (सीएलआर 4.0) डीबगर मेमोरी विंडोज़ में नहीं देख रहा हूं।

यहां एक साधारण कक्षा है जो 16 बाइट उदाहरण उत्पन्न करेगी, ऑब्जेक्ट हेडर कम करेगी।

class Program 
{ 
    short myInt = 2; // 4 bytes 
    long myLong = 3; // 8 bytes 
    string myString = "aString"; // 4 byte object reference 

    // 16 byte instance 

    static void Main(string[] args) 
    { 
     new Program(); 
     return; 
    } 
} 

एक एसओएस वस्तु डंप मुझसे कहता है कि कुल वस्तु आकार 24 बाइट है। यह समझ आता है। मेरा 16 बाइट इंस्टेंस प्लस एक 8 बाइट ऑब्जेक्ट हेडर।

0x0205B660 000d383c 00000003 00000000 0205b678 00000002 ...

और यहाँ तो कुछ टिप्पणियां कर रहे हैं::

offset 0 000d383c ;TypeHandle (pointer to MethodTable), 4 bytes 
offset 4 00000003 00000000 ;myLong, 8 bytes 
offset 12 0205b678 ;myString, 4 byte reference to address of "myString" on GC Heap 
offset 16 00000002 ;myInt, 4 bytes

मेरे वस्तु एक पते 0x0205B660 शुरू होता है

!DumpObj 0205b660 
Name:  Offset_Test.Program 
MethodTable: 000d383c 
EEClass:  000d13f8 
Size:  24(0x18) bytes 
File:  C:\Users\Bob\Desktop\Offset_Test\Offset_Test\bin\Debug\Offset_Test.exe 
Fields: 
     MT Field Offset     Type VT  Attr Value Name 
632020fc 4000001  10   System.Int16 1 instance  2 myInt 
632050d8 4000002  4   System.Int64 1 instance  3 myLong 
631fd2b8 4000003  c   System.String 0 instance 0205b678 myString

यहाँ कच्चे स्मृति है। लेकिन मैं केवल 20 बाइट्स, टाइप हैंडल और इंस्टेंस फ़ील्ड के लिए खाता कर सकता हूं। एक सिंच ब्लॉक सूचक का कोई संकेत नहीं है। ऑब्जेक्ट आकार को 24 बाइट्स के रूप में रिपोर्ट किया गया है, लेकिन डीबगर दिखा रहा है कि इसमें केवल 20 बाइट मेमोरी है।

मैं Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects पढ़ रहा हूँ, और उम्मीद मेरी वस्तु के पहले 4 बाइट्स के रूप में उस लेख के चित्र 8 में दिखाया गया है, एक शून्य सिंक ब्लॉक सूचक माना जाता है। अनुमोदित, यह सीएलआर 1.1 के बारे में एक लेख है।

मैं बस सोच रहा हूं कि मैं जो देख रहा हूं उसके बीच का अंतर और यह प्रारंभिक आलेख रिपोर्ट क्या ऑब्जेक्ट लेआउट के डीबगर के प्रदर्शन में बदलाव है या जिस तरह से सीएलआर 1.1 से बाद के संस्करणों में ऑब्जेक्ट्स देता है ।

वैसे भी, क्या कोई भी मेरे 4 लापता बाइट्स के लिए खाता कर सकता है?

उत्तर

8

मेरा मानना ​​है कि सिंक ब्लॉक स्मृति में ऑब्जेक्ट पॉइंटर के पीछे "पीछे" है। इस तरह एक संदर्भ परिवर्तक सीधे विधि तालिका में इंगित करता है। इसलिए, 0x0205B660 पते पर आपकी ऑब्जेक्ट के लिए, सिंक ब्लॉक 0x0205B65C पते पर होगा।

+2

धन्यवाद सीडी। आप सही हे। 0x0205B660-0x4 मुझे ऑब्जेक्ट हेडर पर ले जाता है जिसमें एक सिंक ब्लॉक इंडेक्स होता है, यदि कोई सेट हो। इसलिए मैंने अपनी ऑब्जेक्ट पर लॉक किया और भाग गया: ! सिंकब्लैक 0x1 सिंच ब्लॉक तालिका में पहली अनुक्रमणिका प्राप्त करने के लिए। आउटपुट मुझे सिंच ब्लॉक इंडेक्स, पता, और मालिक (मेरी वस्तु) देता है। तो ऑब्जेक्ट रेफरेंस प्रकार हैंडल फ़ील्ड को इंगित करता है, और (ऑब्जेक्ट रेफरेंस - 0x4) ऑब्जेक्ट हेडर को इंगित करता है, जिसमें निष्पादन प्रवाह के आधार पर सभी प्रकार की जानकारी होती है। बस मारियो हेवार्ट के "उन्नत .NET डीबगिंग" को उठाया और इसमें इस सामान को विस्तार से शामिल किया गया। एक बार फिर धन्यवाद। – user314045

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