2012-09-08 10 views
10

जानने के लिए मेरी कक्षा में बर्बाद हम एक काम और प्रश्नों में से एक में कहा गया है:जानबूझकर मुख्य स्मृति के सभी विखंडन

सी में

मेमोरी विखंडन: डिजाइन, लागू करने, और एक सी प्रोग्राम है कि चलाने निम्नलिखित: यह आकार 500000 तत्वों के आकार के 3 मीटर सरणी के अनुक्रम के लिए स्मृति आवंटित किया गया; तो यह सभी भी क्रमांकित सरणी को हटा देता है और आकार 700000 तत्वों के आकार के एम सरणी का अनुक्रम आवंटित करता है। पहले अनुक्रम के आवंटन और दूसरे अनुक्रम के लिए आपके कार्यक्रम की आवश्यकता के समय की मात्रा को मापें। एम चुनें ताकि आप अपने कार्यक्रम में उपलब्ध सभी मुख्य स्मृति को समाप्त कर सकें। अपने समय के बारे में बताएं

इस बात का मेरे कार्यान्वयन इस प्रकार है:

#include <iostream> 
#include <time.h> 
#include <algorithm> 

void main(){ 
    clock_t begin1, stop1, begin2, stop2; 
    double tdif = 0, tdif2 = 0; 
    for(int k=0;k<1000;k++){ 
    double dif, dif2; 
    const int m = 50000; 
    begin1 = clock(); 
    printf("Step One\n"); 
    int *container[3*m]; 
    for(int i=0;i<(3*m);i++) 
    { 
     int *tmpAry = (int *)malloc(500000*sizeof(int)); 
     container[i] = tmpAry; 
    } 
    stop1 = clock(); 
    printf("Step Two\n"); 
    for(int i=0;i<(3*m);i+=2) 
    { 
    free(container[i]); 
    } 
    begin2 = clock(); 
    printf("Step Three\n"); 
    int *container2[m]; 
    for(int i=0;i<m;i++) 
    { 
    int *tmpAry = (int *)malloc(700000*sizeof(int)); 
    container2[i] = tmpAry; 
    } 
    stop2 = clock(); 
    dif = (stop1 - begin1)/1000.00; 
    dif2 = (stop2 - begin2)/1000.00; 
    tdif+=dif; 
    tdif/=2; 
    tdif2+=dif2; 
    tdif2/=2; 
} 
printf("To Allocate the first array it took: %.5f\n",tdif); 
printf("To Allocate the second array it took: %.5f\n",tdif2); 
system("pause"); 
}; 

मैं इस अप बदल दिया है कुछ भिन्न तरीकों, लेकिन consistencies मैं देख रहा हूँ कि जब मैं शुरू में 3 के लिए स्मृति को आबंटित कर रहे हैं * एम * 500000 तत्व सरणी यह ​​सभी उपलब्ध मुख्य स्मृति का उपयोग करता है। लेकिन फिर जब मैं उन्हें मुक्त करने के लिए कहता हूं तो स्मृति को ओएस पर वापस नहीं छोड़ा जाता है, इसलिए जब यह एम * 700000 तत्व सरणी आवंटित करने के लिए जाता है तो यह पृष्ठ फ़ाइल (स्वैप मेमोरी) में करता है, इसलिए यह वास्तव में स्मृति विखंडन प्रदर्शित नहीं करता है ।

उपर्युक्त कोड इस 1000 बार चलता है और औसत बनाता है, इसमें काफी समय लगता है। पहले अनुक्रम औसत ने 2.06913 सेकंड लिया और दूसरा अनुक्रम 0.675 9 4 सेकंड लिया। मेरे लिए दूसरा अनुक्रम यह दिखाने के लिए अधिक समय लेना चाहिए कि विखंडन कैसे काम करता है, लेकिन इसका इस्तेमाल होने वाले स्वैप के कारण ऐसा नहीं होता है। क्या इस बारे में कोई रास्ता है या क्या मैं अपनी धारणा में गलत हूं?

मैं प्रोफेसर से पूछता हूं कि मेरे पास सोमवार को क्या है लेकिन तब तक किसी भी मदद की सराहना की जाएगी।

+1

"एम चुनें ताकि आप अपने कार्यक्रम के लिए उपलब्ध सभी मुख्य स्मृति को समाप्त कर सकें" - जो कि कुछ प्रणालियों पर वास्तव में कठिन हो सकता है।जैसा कि मैंने टाइप किया है, मेरे पास 2 जीबी मुख्य मेमोरी है, लेकिन 32 बिट विंडोज़ पर एक प्रक्रिया केवल 2 जीबी वर्चुअल एड्रेस स्पेस का उपयोग कर सकती है। अगर मेरे पास 3 जीबी की मुख्य मेमोरी थी, तो एक प्रक्रिया के लिए यह सब असंभव होगा। हालांकि, मुझे याद नहीं है कि सभी 32 बिट प्रक्रियाएं समान 2 जीबी साझा करती हैं और अन्य 1 जीबी केवल ओएस और ड्राइवरों द्वारा उपयोग की जाती है, या 32 बिट विंडोज प्रक्रियाओं के बीच 3 जीबी सही तरीके से साझा करने में सक्षम है या नहीं। –

+3

कुछ ऑपरेटिंग सिस्टम मुख्य स्मृति को तब तक निर्दिष्ट नहीं करेंगे जब तक कि यह वास्तव में लिखा न जाए, इसलिए आपके समय का विखंडन के मामले में अधिक मतलब नहीं हो सकता है। यह सिर्फ वर्चुअल रूप से खंडित हो सकता है। –

+3

जांचने के लिए कुछ और: आपके ओएस और सेटिंग्स के आधार पर, आप 'malloc' में' mmap' थ्रेसहोल्ड मार रहे हैं। 50000 तत्व केवल 'M_MMAP_MAX' के डिफ़ॉल्ट मान के अंतर्गत हैं, और यदि आप 32-बिट लिनक्स पर हैं, तो ब्लॉक 'M_MMAP_THRESHOLD' से अधिक हैं। यदि आप वास्तव में ढेर का उपयोग करने के बजाय 'mmap' ट्रिगर कर रहे हैं, तो आवंटन व्यक्तिगत मैपिंग के रूप में समाप्त होता है, और विखंडन से पीड़ित नहीं होता है। ब्लॉक के आकार को कम करने का प्रयास करें। –

उत्तर

2

कई libc कार्यान्वयन (मुझे लगता है कि glibc शामिल है) जब आप free() पर कॉल करते हैं तो स्मृति को वापस ओएस पर रिलीज़ न करें, लेकिन इसे रखें ताकि आप बिना किसी सिस्कल के अगले आवंटन पर इसका उपयोग कर सकें। इसके अलावा, आधुनिक पेजिंग और वर्चुअल मेमोरी स्ट्रैटजीज की जटिलता के कारण, आप कभी भी यह सुनिश्चित नहीं कर सकते कि भौतिक स्मृति में कुछ भी कहां है, जो जानबूझकर इसे खंडित करने के लिए लगभग असंभव बनाता है (भले ही यह खंडित हो)। आपको याद रखना होगा, सभी वर्चुअल मेमोरी, और सभी भौतिक मेमोरी अलग-अलग जानवर हैं।

(निम्नलिखित लिनक्स के लिए लिखा है, लेकिन शायद Windows और OSX के लिए लागू)

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

याद रखें, लगातार वर्चुअल पतों का एक सेट अभ्यास में (या यहां तक ​​कि स्मृति में) शारीरिक रूप से निरंतर नहीं है।

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