2012-02-03 15 views
6

वर्चुअल मेमोरी में हेरफेर करने के लिए मैं mmap() का उपयोग करने का प्रयास करता हूं। मैं स्मृति के क्षेत्र को आरक्षित और प्रतिबद्ध करना चाहता हूं। मैंने इस कोड का परीक्षण किया:क्यों बड़े आकार के साथ mmap() कॉलिंग विफल नहीं है?

const unsigned long gygabyte = 1024 * 1024 * 1024; 
const unsigned long gygabyteCount = 2; 
const unsigned long maxCapacity = gygabyteCount * gygabyte; 

int main() 
{ 
    char* pMemory; 

    pMemory = (char*)mmap(NULL, maxCapacity, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 
    if (mprotect(pMemory, maxCapacity, PROT_READ | PROT_WRITE) != 0) 
    { 
     cout << "Memory Allocation has failed" << endl; 
    } 
    usleep(-1); 

    return 0; 
} 

मैंने टर्मिनल से अपने प्रोग्राम (6 कहें) की कई प्रतियां चलाईं। मैंने कभी भी "मेमोरी आवंटन विफल नहीं हुआ" देखा है। मैं 4 जीबी रैम के साथ 64-बिट उबंटू पर चल रहा हूं। क्या कोई मुझे इस बारे में कुछ बता सकता है?

+1

मेमोरी ओवरकॉमिट – PlasmaHH

+0

के बारे में पढ़ें आपके द्वारा पोस्ट किया गया कोड कुछ भी नहीं करता है। उन स्मृति क्षेत्रों के माध्यम से चलने का प्रयास करें। – Mat

उत्तर

11

mmap के एक क्षेत्र को सुरक्षित रखता है प्रक्रिया की आभासी पता स्थान, लेकिन इसके लिए भौतिक RAM आवंटित नहीं करता है। इसलिए, 64-बिट प्लेटफार्म पर, आप असफलता के बिना एक विशाल राशि आरक्षित कर सकते हैं (हालांकि आपको अभी भी विफलता की जांच करने की आवश्यकता है; आपका उदाहरण कोड नहीं है)। जब स्मृति का उपयोग किया जाता है तब रैम के भौतिक पृष्ठ आवंटित किए जाते हैं।

mprotect बस आरक्षित स्मृति के पढ़ने/लिखने के उपयोग को बदलता है; यह रैम में इसे निवासी नहीं बनायेगा। आपको PROT_NONEmmap के बजाय पर कॉल को हटाकर एक ही प्रभाव प्राप्त होगा।

यदि आपको सीधे RAM में निवासी होने की स्मृति की आवश्यकता है, तो उसके लिए mlock का उपयोग करें। यदि पर्याप्त रैम उपलब्ध नहीं है तो यह असफल हो जाएगा। कई लिनक्स प्लेटफ़ॉर्म (उबंटू समेत) पर, संसाधन सीमा (RLIMIT_MEMLOCK) है जो प्रतिबंधित करती है कि कोई भी प्रक्रिया कितनी मेमोरी लॉक कर सकती है; आप ulimit -l के साथ इसे समायोजित कर सकते हैं।

+0

यह इस तरह दिखना चाहिए? 'pMemory = (char *) mmap (NULL, maxCapacity, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); mlock (pmemory, maxCapacity) 'मुझे लगता है कि mlock() में उपयोग की गई स्मृति mmap() द्वारा आरक्षित स्मृति नहीं है। – antpetr89

+0

मैंने 1 जीबी आरक्षित करने की कोशिश की और उन्हें इस तरह से प्रतिबद्ध किया। लेकिन mlock() लौटा -1। – antpetr89

+1

@ user1173593: बाद में 'errno' के मान की जांच करें। यह 'EPERM' हो सकता है, जो दर्शाता है कि आपकी संसाधन सीमा बहुत कम है (आप इसे' ulimit -l' के साथ सेट कर सकते हैं, लेकिन शायद एक कठिन सीमा भी है), या शायद 'ENOMEM', यह दर्शाती है कि पर्याप्त स्मृति नहीं है , या मैनपेज में प्रलेखित अन्य त्रुटियां। –

0

आपको पहले mmap का परिणाम देखना चाहिए। यदि यह MAP_FAILED देता है, तो इसका मतलब है कि आवंटन विफल हो गया है। कर्नेल वास्तव में एक बार में इतनी मेमोरी आवंटित नहीं करेगा, लेकिन जब आप उस ब्लॉक के संबंधित क्षेत्रों तक पहुंचते हैं तो मांग पर भौतिक या स्वैप किए गए स्थान को मानचित्रित करेंगे।

अपने विशेष मामले में आप, mprotect को एक अलग कॉल की जरूरत नहीं है पूरे क्षेत्र के लिए इन झंडे गुजर mmap बुला के समय में किया जा सकता है के बाद से:

pMemory = mmap(NULL, maxCapacity, 
    PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 

if (pMemory == MAP_FAILED) { 
    /* allocation failed */ 
} 
1

mmap आपके द्वारा मांगी गई मेमोरी की मैपिंग तैयार करने के लिए उपयोगी है, लेकिन यह आपके प्रोग्राम में आवंटित नहीं करता है। जब आप इसे एक्सेस करते हैं तो कर्नेल मेमोरी आवंटित करने का ख्याल रखता है, इस प्रकार mmap -8 जीबी 4 जीबी मेमोरी पर संभव है, यदि आप एक साथ 8 जीबी तक नहीं पहुंचते हैं।

echo "2" > /proc/sys/vm/overcommit_memory 

अन्यथा यह (से जब लिनक्स एक खिलौना ओएस था) असीमित ओवरकमिट की इजाजत दी और बुरी तरह आपकी ऐप्लिकेशन बनाने की विरासत डिफ़ॉल्ट रखता है:

0

सबसे पहले, आप लिनक्स बताने के लिए आप इसे लेखांकन प्रतिबद्ध क्या करना चाहते है जब वे शारीरिक स्मृति से बाहर निकलते हैं तो दुर्घटनाग्रस्त हो जाती है।

इसके अलावा, के रूप में दूसरों ने कहा है, आप MAP_FAILED के खिलाफ mmap के रिटर्न मान जांच करने की आवश्यकता है, और mprotect उपयोग करने के लिए कोई आवश्यकता नहीं है। बस शुरू करने के लिए PROT_* से mmap के सही मानों को पारित करें।

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