2010-11-01 15 views
5

गिनती के दो पूरक पूरक गणित की एक पंक्ति की व्याख्या करें मेरे पास विंडोज मोबाइल 6.x के लिए एक विजुअल स्टूडियो 2008 सी ++ एप्लिकेशन है जहां मैं किसी दिए गए प्रक्रिया के लिए मुफ्त वर्चुअल मेमोरी की मात्रा की गणना कर रहा हूं। (मुझे पता है यह खाते में विखंडन नहीं ले रही है।) मेरी कोड इस तरह मूल रूप से दिखता है:दो वर्चुअल मेमोरी

MEMORY_BASIC_INFORMATION mbi = { 0 }; 

/// total free memory available to the process 
DWORD free = 0; 

/// base memory address for the given process index (2-33). 
DWORD slot_base_addr = process_index * 0x02000000; 

/// look at each memory region for the process. 
for(DWORD offset = 0x10000; 
    offset < 0x02000000; 
    offset += mbi.RegionSize) 
{ 
    ::VirtualQuery((void*)(slot_base_addr + offset), 
        &mbi, 
        sizeof(MEMORY_BASIC_INFORMATION)); 

    if(mbi.State == MEM_FREE) 
    { 
     free += (mbi.RegionSize - ((~(DWORD)mbi.BaseAddress + 1) & 0xffff)) & 0xffff0000; 
    } 
} 
NKDbgPrintfW(L"%d bytes free\r\n", free); 

मैं इस पूरी तरह से काम करने लगता है कि अन्य API के साथ इस बात की पुष्टि कर सकते हैं। मेरा प्रश्न है कि इस लाइन कर रहा है:

free += (mbi.RegionSize - ((~(DWORD)mbi.BaseAddress + 1) & 0xffff)) & 0xffff0000; 

यह सिर्फ नहीं क्यों है:

free += mbi.RegionSize; 

मैं एक Usenet पद MSFT कर्मचारी रॉस जॉर्डन के द्वारा पर पूर्व लाइन पाया।

धन्यवाद, PaulH


संपादित करें:

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

Slot: 2. Range: 0x04000000 - 0x06000000 
    RS: 16,384 bytes RJ:   0 bytes diff: 16384 
    RS:  4,096 bytes RJ:   0 bytes diff: 4096 
    RS:  4,096 bytes RJ:   0 bytes diff: 4096 
    RS:  4,096 bytes RJ:   0 bytes diff: 4096 
    RS:  4,096 bytes RJ:   0 bytes diff: 4096 
    RS:  4,096 bytes RJ:   0 bytes diff: 4096 
    RS: 36,864 bytes RJ:   0 bytes diff: 36864 
    RS: 65,536 bytes RJ: 65,536 bytes diff: 0 
    RS: 53,248 bytes RJ:   0 bytes diff: 53248 
    RS:  4,096 bytes RJ:   0 bytes diff: 4096 
    RS:  4,096 bytes RJ:   0 bytes diff: 4096 
    RS:  4,096 bytes RJ:   0 bytes diff: 4096 
    RS:  4,096 bytes RJ:   0 bytes diff: 4096 
    RS:  4,096 bytes RJ:   0 bytes diff: 4096 
    RS: 7,671,808 bytes RJ: 7,667,712 bytes diff: 4096 
    RS: 1,921,024 bytes RJ: 1,900,544 bytes diff: 20480 
    RS: 7,491,584 bytes RJ: 7,471,104 bytes diff: 20480 
    RS: 3,252,224 bytes RJ: 3,211,264 bytes diff: 40960 
    RS: 262,144 bytes RJ: 262,144 bytes diff: 0 

RS: Total VM Free: 20,811,776 bytes. 
RJ: Total VM Free: 20,578,304 bytes. 

संपादित करें 2:

हंस मुझे जवाब देने के लिए नेतृत्व किया। यह करने का यह एक शानदार तरीका है, लेकिन यह मानते हुए कि आवंटन आकार 64 केबी है।

SYSTEM_INFO si = { 0 }; 
::GetSystemInfo(&si); 

free += mbi.RegionSize - mbi.RegionSize % si.dwAllocationGranularity; 

उत्तर

2

वर्चुअलअलोक के लिए आवंटन ग्रैन्युलरिटी सामान्यतः 64 केबी है। यदि आवंटनबेस 64 केबी का बहुमत नहीं है तो वह कुछ सार्थक करने की कोशिश करता है। मुझे नहीं लगता कि यह अर्थपूर्ण है, उसके बिटकमास्क अभी भी 64 केबी की ग्रैन्युलरिटी मानते हैं और वह SYSTEM_INFO.dwAllocationGranularity का उपयोग नहीं करता है।

यह मान कठिन में 64 KB अतीत के रूप में कोडित किया गया था, लेकिन अन्य हार्डवेयर आर्किटेक्चर अलग मूल्यों की आवश्यकता हो सकती: इस टिप्पणी है जो।

बहुत दुर्लभ मामले में जहां यह 64 केबी नहीं है, यह कोड जंक मान उत्पन्न करेगा। बस इसे ज़ैप करें, RegionSize द्वारा जाएं।

+0

इसमें कुछ महत्वपूर्ण है। उस एल्गोरिदम द्वारा दी गई 'वर्तमान प्रक्रिया' के लिए उपलब्ध स्मृति 'GlobalMemoryStatus()' कहती है कि यह क्या है। अगर मैं सिर्फ 'क्षेत्र आकार' से जाता हूं, तो परिणाम लगातार दो दर्जन केबी द्वारा छोटा होता है। संदर्भ के लिए, मेरे dwAllocationGranularity 64KB है। – PaulH

+0

एर्म, यह कैसे संभव है? कथन * क्षेत्र आकार से * घटाता है। यह केवल इसे छोटा कर सकता है, बड़ा नहीं। यदि आपको GlobalMemoryStatus पसंद है, तो शायद आपको इसका उपयोग करना चाहिए। –

+0

+1, विंडोज मोबाइल 'अन्य हार्डवेयर एच्इटेक्चर' –

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

  • कोई संबंधित समस्या नहीं^_^