2009-08-13 10 views
9

से लिया गया मेमोरी मैं सोच रहा था कि "ऑब्जेक्ट" से प्राप्त ऑब्जेक्ट कितनी मेमोरी है और इसमें कोई फ़ील्ड/गुण नहीं हैं? और मुझे लगता है कि तरीके नहीं हैं। सही ? मैं .NET वस्तुओं के लिए बात कर रहा हूँ।एक सी # ऑब्जेक्ट

+0

अच्छा सवाल। मैं कहूंगा कि उनमें से कुछ मिलियन बनाएं और पहले और बाद में स्मृति अंतर देखें। जब तक कि कोई पहले से ही ऐसा नहीं कर लेता है। –

+0

Thats क्यों मैंने पूछा। मुझे लाखों वस्तुओं के साथ आवेदन के स्मृति उपयोग को जानने की जरूरत थी। तो 32 बिट ऐप का उत्तर सभी फ़ील्ड +8 बाइट्स का आकार है। –

उत्तर

11

ठीक है, दोनों एंड्रयू और Guffa जवाब जो मैं गलत प्रतीत होने वाली ... दे दिया है के रूप में

वहाँ सभी वस्तुओं (86 पर) के लिए एक 8 बाइट भूमि के ऊपर है, लेकिन वहाँ भी 12 की एक न्यूनतम आकार बाइट्स। मैं पता नहीं क्यों ... लेकिन इसका मतलब है कि इन दो वर्गों दोनों उदाहरण प्रति 12 बाइट्स ले:

public class OneField 
{ 
    private int field; 
} 

public class NoFields 
{ 
} 

टेस्ट:

using System; 

public class OneField 
{ 
    private int field; 
} 

public class NoFields {} 

public class Test 
{ 
    static void Main(string[] args) 
    { 
     int size = int.Parse(args[0]); 
     switch (args[1]) 
     { 
      case "NoFields": 
       TestNoFields(size); 
       break; 
      case "OneField": 
       TestOneField(size); 
       break; 
     } 
    } 

    static void TestNoFields(int size) 
    { 
     NoFields[] array = new NoFields[size]; 
     long start = GC.GetTotalMemory(true); 
     for (int i=0; i < size; i++) 
     { 
      array[i] = new NoFields(); 
     } 
     long end = GC.GetTotalMemory(true); 
     GC.KeepAlive(array); 
     Console.WriteLine("Size per instance: {0}", 
          (end-start)/(double)size); 
    } 

    static void TestOneField(int size) 
    { 
     OneField[] array = new OneField[size]; 
     long start = GC.GetTotalMemory(true); 
     for (int i=0; i < size; i++) 
     { 
      array[i] = new OneField(); 
     } 
     long end = GC.GetTotalMemory(true); 
     GC.KeepAlive(array); 
     Console.WriteLine("Size per instance: {0}", 
          (end-start)/(double)size); 
    } 
} 

यह बदसूरत है क्योंकि मैं जानबूझ कर नहीं किया है किसी भी सामान्य प्रकार या किसी और चीज के लिए चला गया जो मुद्दों का कारण बन सकता है। कुछ परीक्षण चलाता है:

>test 1000000 NoFields 
Size per instance: 12.000024 
>test 1000000 OneField 
Size per instance: 12.000024 
>test 1000 NoFields 
Size per instance: 12 
>test 1000 OneField 
Size per instance: 12 

(JITting भूमि के ऊपर आदि बताता है कि क्यों संख्या हमेशा एक सटीक पूर्णांक नहीं है - इसलिए कारण है कि मैं चल बिन्दु में विभाजन है।)

परीक्षण एक अतिरिक्त पूर्णांक क्षेत्र शो के साथ उपयोग 16 तक जा रहा है, जो साबित करता है कि यह वास्तव में कुछ समझदार है :)

+0

न्यूनतम 12 बाइट के बारे में अच्छा बिंदु लेकिन मुझे लगता है कि प्रश्न की भावना से संबंधित है कि 'System.Object' से "विरासत" कितनी जानकारी है। हालांकि आप सही हैं कि x86 पर, पहला फ़ील्ड बोलने के लिए "फ्री" है, लेकिन 'System.Object' के ऊपरी हिस्से के बिना, पहले 3 फ़ील्ड मुफ्त में हो सकते थे :) फिर भी, इस महत्वपूर्ण भेद के लिए आपको +1 करें। –

0

एक संदर्भ प्रकार के साथ आप एकमात्र ओवरहेड टाइप ऑब्जेक्ट पॉइंटर और सिंक ब्लॉक इंडेक्स के लिए 4 बाइट्स के लिए 4 बाइट होंगे।

तो कुल मिलाकर, 8 बाइट ओवरहेड।

3

किसी ऑब्जेक्ट के अपने डेटा के लिए दो संदर्भ/पॉइंटर्स अतिरिक्त हैं।

तो, 32 बिट सिस्टम पर ऑब्जेक्ट 8 बिट्स लेगा, 64 बिट सिस्टम पर यह 16 बाइट्स लेगा।

सुधार:
जैसा कि जॉन ने कहा, एक वस्तु के लिए न्यूनतम आकार 12 बाइट है। अब तक जो जानकारी मिली है, वह कहती है कि जीसी को इसकी आवश्यकता है।

+4

नहीं - किसी कारण से x86 पर 12 बाइट्स का न्यूनतम ऑब्जेक्ट आकार है, लेकिन आपको पहला फ़ील्ड "फ्री" मिलता है :) –

+0

इस http://msdn.microsoft.com/en-us/magazine/cc163791 के अनुसार .aspx जीसी को ऑब्जेक्ट को किसी कारण से कम से कम 12 बाइट्स की आवश्यकता होती है। – Guffa

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