2009-05-14 21 views
6

मैंने लिनक्स में एक सी प्रोग्राम लिखा है जो मैलॉक्स मेमोरी है, इसे लूप में चलाया गया है, और टॉप ने कोई स्मृति खपत नहीं दिखायी है।कुछ आवंटकों आलसी हैं?

तब मैंने उस स्मृति के साथ कुछ किया है, और टॉप ने स्मृति खपत दिखायी है।

जब मैं malloc, क्या मैं वास्तव में "स्मृति प्राप्त करें", या वहाँ एक "आलसी" स्मृति प्रबंधन है, जो केवल मुझे स्मृति देता है अगर मैं इसका उपयोग करता हूं?

(वहाँ भी एक विकल्प शीर्ष कि केवल स्मृति की खपत के बारे में पता है जब मैं इसका इस्तेमाल है, इसलिए मैं इस बारे में यकीन नहीं है ..)

धन्यवाद

उत्तर

15

लिनक्स पर, malloc sbrk के साथ स्मृति का अनुरोध करता है() या mmap() - किसी भी तरह से, आपकी पता स्थान तुरंत विस्तारित हो जाती है, लेकिन लिनक्स भौतिक स्मृति के वास्तविक पृष्ठों को तब तक निर्दिष्ट नहीं करता जब तक कि प्रश्न में पृष्ठ पर पहली बार लिखा न जाए। आप वीआईआरटी कॉलम में एड्रेस स्पेस विस्तार देख सकते हैं, जबकि आरईएस में वास्तविक, भौतिक स्मृति उपयोग।

+0

विंडोज़ के लिए समान है? – TStamper

+0

मैं विंडोज़ से क्या परिचित नहीं हूं, क्षमा करें। – bdonlan

+0

bdonlan: सही है, लेकिन वह प्रभाव का कांटा के लिए बाहर देखना चाहिए "। * बच्चे अपने माता-पिता की स्मृति ताले वारिस नहीं करता है (mlock (2), mlockall (2)) " कौन कैसे सबसे एप्लिकेशन के लोड हो जाएगा जब वह शीर्ष पर देख रहा है – RandomNickName42

3

हां, जब तक आप इसे स्पर्श नहीं करते हैं, तब तक स्मृति को आपके मेमोरी स्पेस में मैप नहीं किया जाता है। mallocing स्मृति केवल पेजिंग टेबल सेट करेगा ताकि वे आवंटित स्मृति में पेजफॉल्ट प्राप्त कर सकें, स्मृति को मैप किया जाना चाहिए।

0

क्या आप कंपाइलर अनुकूलन का उपयोग कर रहे हैं? हो सकता है कि ऑप्टिमाइज़र ने आवंटन को हटा दिया हो क्योंकि आप आवंटित संसाधनों का उपयोग नहीं कर रहे हैं?

+0

धन्यवाद रयान, मैंने डिस्सेबलर के साथ बाइनरी को देखा और 'मॉलोक' कॉल वहां था। नकारात्मक वोटों का मुकाबला करने के लिए –

+0

+1। सवाल के लिए यह एक अच्छा जवाब है जैसा कि यह है। –

+1

कंपाइलर बिना किसी कार्यान्वयन के एक फ़ंक्शन को हटा सकता है या जिस पर दुष्प्रभाव हो सकते हैं। – BeeOnRope

3

यह थोड़ा सा विषय शुरू करता है (और फिर मैं इसे आपके प्रश्न में जोड़ दूंगा), लेकिन क्या हो रहा है जब आप लिनक्स में एक प्रक्रिया को फोर्क करते हैं तो क्या होता है। जब फोर्किंग एक प्रतिलिपि है जिसे प्रतिलिपि पर कॉपी कहा जाता है जो स्मृति को भी लिखा जाता है जब नई प्रक्रिया के लिए केवल स्मृति स्थान की प्रतिलिपि बनाता है। इस तरह अगर फोर्कड प्रोसेस निष्पादन तुरंत एक नया प्रोग्राम है तो आपने मूल प्रोग्राम मेमोरी की प्रतिलिपि बनाने के ओवरहेड को सेव किया है।

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

इसका उद्देश्य क्या है? यह मूल रूप से मैलोकिंग मेमोरी को बिग ओ (एन) ऑपरेशन के बजाय बिग ओ (1) की तुलना में कम या अधिक स्थिर समय ऑपरेशन बनाता है (जिस तरह से लिनक्स शेड्यूलर इसे एक बड़े हिस्से में करने के बजाए इसे बाहर कर देता है)।

प्रदर्शित करने के लिए मैं क्या मतलब है मैं निम्नलिखित प्रयोग किया:

[email protected]s-desktop:~/test_code$ time ./bigmalloc 

real 0m0.005s 
user 0m0.000s 
sys 0m0.004s 
[email protected]:~/test_code$ time ./deadbeef 

real 0m0.558s 
user 0m0.000s 
sys 0m0.492s 
[email protected]:~/test_code$ time ./justwrites 

real 0m0.006s 
user 0m0.000s 
sys 0m0.008s 

bigmalloc कार्यक्रम 20 मिलियन ints आबंटित करता है, लेकिन उनके साथ कुछ भी नहीं है। डेडबीफ 1 9 51 में लिखने वाले प्रत्येक पृष्ठ के लिए एक int लिखता है और लिखता है और लिखता है 1 9 31 के इनट्स को आवंटित करता है और उन्हें शून्य करता है। जैसा कि आप देख सकते हैं कि डेडबीफ को bigmalloc से निष्पादित करने के लिए लगभग 100 गुना अधिक समय लगता है और केवल लिखने से 50 गुना लंबा होता है।

#include <stdlib.h>  

int main(int argc, char **argv) { 

int *big = malloc(sizeof(int)*20000000); // allocate 80 million bytes 

return 0; 

} 

#include <stdlib.h>  

int main(int argc, char **argv) { 

int *big = malloc(sizeof(int)*20000000); // allocate 80 million bytes 

// immediately write to each page to simulate all at once allocation 

// assuming 4k page size on 32bit machine 

for (int* end = big + 20000000; big < end; big+=1024) *big = 0xDEADBEEF ;  

return 0; 

} 

#include <stdlib.h> 

int main(int argc, char **argv) { 

int *big = calloc(sizeof(int),19531); // number of writes 

return 0; 
} 
+0

बहुत बढ़िया जवाब, धन्यवाद! (यह जानकर आश्चर्य हुआ कि 0xDEADBEAF एक ज्ञात शब्द है http://en.wikipedia.org/wiki/Hexspeak) –

0

सुविधा ओवरकमिट कहा जाता है - कर्नेल "वादों" डेटा खंड आकार बढ़ाकर आप स्मृति, लेकिन यह करने के लिए भौतिक स्मृति को आबंटित नहीं है।जब आप उस नई जगह में किसी पते को स्पर्श करते हैं तो प्रक्रिया पृष्ठ-कर्नेल में दोष होता है, जो उसके बाद भौतिक पृष्ठों को मैप करने का प्रयास करता है।

0

हाँ, ध्यान दें VirtualAlloc झंडे

MEM_RESERVE 
MEM_COMMIT 

हे, लेकिन के लिए लिनक्स, या किसी भी POSIX/BSD/SVR# प्रणाली, vfork(), उम्र के लिए चारों ओर गया है और simular सुविधा प्रदान करता है है।

vfork() फ़ंक्शन कांटा से अलग है() है कि बच्चे प्रक्रिया में केवल बुला प्रक्रिया (मूल प्रक्रिया) के साथ कोड और डेटा साझा कर सकते हैं। यह vfork() का दुरुपयोग होने पर अभिभावक प्रक्रिया की अखंडता के जोखिम पर महत्वपूर्ण रूप से क्लोनिंग गतिविधि को गति देता है।

किसी भी उद्देश्य के लिए () vfork के उपयोग के कार्यकारी परिवार से एक समारोह के लिए एक तत्काल कॉल करने के लिए एक प्रस्तावना के रूप में छोड़कर, या _exit करने के लिए(), सलाह नहीं दी है।

vfork() फ़ंक्शन पूरी तरह से वर्ष प्रक्रिया का पता स्थान को कॉपी किए बिना नई प्रक्रियाओं बनाने के लिए इस्तेमाल किया जा सकता है। यदि फोर्क की गई प्रक्रिया बस निष्पादित करने के लिए जा रही है, तो डेटा स्पेस माता-पिता से फोर्क() द्वारा प्रतिलिपि बनाई गई है। यह विशेष रूप से उपयोगी है, जो विशेष रूप से उपयोगी vfork() बनाते हुए एक पेजेड पर्यावरण में अक्षम है। पर निर्भर करता है कि माता-पिता की डेटा स्पेस का आकार vfork() फोर्क() पर एक महत्वपूर्ण प्रदर्शन सुधार दे सकता है।

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