आवंटित स्मृति पर क्या यह कभी भी ठीक नहीं है * * का उपयोग मुफ्त ()?


83

मैं कंप्यूटर इंजीनियरिंग का अध्ययन कर रहा हूं, और मेरे पास कुछ इलेक्ट्रॉनिक्स पाठ्यक्रम हैं। मैं (इन पाठ्यक्रमों की) है कि इसके उपयोग से बचने के लिए संभव है मेरी प्रोफेसरों के दो से सुना, free()समारोह (के बाद malloc(), calloc()आदि) क्योंकि स्मृति संभावना आवंटित फिर से उपयोग नहीं किया जाएगा रिक्त स्थान अन्य स्मृति को आबंटित करने। उदाहरण के लिए, यदि आप 4 बाइट आवंटित करते हैं और फिर उन्हें जारी करते हैं, तो आपके पास 4 बाइट्स स्थान होगा जो संभवतः फिर से आवंटित नहीं किया जाएगा: आपके पास एक छेद होगा

मुझे लगता है कि वह पागल है: आपके पास एक खिलौना-कार्यक्रम नहीं हो सकता है जहां आप इसे जारी किए बिना ढेर पर मेमोरी आवंटित करते हैं। लेकिन मेरे पास यह समझाने के लिए ज्ञान नहीं है कि यह इतना महत्वपूर्ण क्यों है कि प्रत्येक के लिए एक malloc()होना चाहिए free()

तो: क्या कभी ऐसी परिस्थितियाँ हैं जिनमें malloc()बिना उपयोग के उपयोग करना उचित हो सकता है free()? और यदि नहीं, तो मैं अपने प्रोफेसरों को यह कैसे समझा सकता हूं?


11
वे "गलत" नहीं हैं - उनके पास बहुत छोटे पृथक मुक्त क्षेत्रों के विखंडन के बारे में एक वैध (यदि सीमित है) बिंदु है, और शायद आपने इसे रिपोर्ट किया है, तो इसे थोड़ा और अधिक सावधानी से कहा गया है।
क्रिस स्ट्रैटन

2
केवल एक बार आपको मुफ्त मेमोरी की आवश्यकता नहीं है, प्रबंधित मेमोरी का उपयोग करते समय या जब आप मूल आवंटित मेमोरी का पुन: उपयोग करने जा रहे हों। मुझे संदेह है कि कारण दो प्रशिक्षकों ने यह कहा है क्योंकि आप एक विशिष्ट कार्यक्रम के बारे में बात कर रहे हैं जो स्मृति का पुन: उपयोग कर सकता है। इस मामले में आप अभी भी मुफ्त () का उपयोग करेंगे लेकिन केवल अपने आवेदन के अंत में। क्या आप सुनिश्चित हैं कि यह उनका अर्थ नहीं था?
क्रोव

17
@ मेरियन: मेरे पास एक प्रोफेसर का दावा था कि C और C ++ में आपकी आवंटित स्मृति को उसी .c / .cxx फ़ाइल में परिभाषित फ़ंक्शन में मुक्त करना आवश्यक है क्योंकि इसे आवंटित किया गया था ... ये लोग कभी-कभी हाइपोक्सिया से गंभीर रूप से पीड़ित लगते हैं। हाथीदांत टॉवर में बहुत अधिक रहने के कारण।
१०:२२ पर प्लाज्मा

4
ऐसे कुछ नॉन-टॉय प्रोग्राम हैं, जो मेमोरी को डिले नहीं करते हैं, और ओएस को प्रोसेस एग्जिट पर यह सब साफ करने देते हैं (बहुत आसानी से) बुक-कीपिंग की तुलना में बहुत अधिक है ताकि आप इसे खुद कर सकें।
डोनाल्ड फेलो

9
आपके दिमाग में सुनाई गई सामग्री को कभी भी निर्विवाद रूप से न मिलाएं। मेरे पास कई शिक्षक और लेक्टर और सुधारक थे जो गलत थे या पुराने थे। और हमेशा विश्लेषण करें कि वे क्या कहते हैं। हमारा लोक अक्सर काफी सटीक होता है और वह सामान कह सकता है जो सही है, लेकिन गलत तरीके से या किसी व्यक्ति द्वारा गलत प्राथमिकता के साथ समझना आसान है जो केवल आम बोलचाल में घर महसूस करता है। जैसे, मुझे स्कूल में याद है, एक शिक्षक ने कहा "क्या आपने अपना होमवर्क किया है।", मैंने कहा "नहीं।" जब मैं सही था, शिक्षक को यह आपत्तिजनक लगा, क्योंकि मैंने लंगड़ा बहाना खोजने के लिए समय बचाया, जिसकी उन्हें उम्मीद नहीं थी।
सेबेस्टियन मच

जवाबों:


100

आसान: बस किसी भी आधे-गंभीर malloc()/free()कार्यान्वयन के स्रोत को पढ़ें । इसके द्वारा, मेरा मतलब वास्तविक मेमोरी मैनेजर है जो कॉल का काम संभालता है। यह रनटाइम लाइब्रेरी, वर्चुअल मशीन या ऑपरेटिंग सिस्टम में हो सकता है। बेशक कोड सभी मामलों में समान रूप से सुलभ नहीं है।

सुनिश्चित करें कि मेमोरी को खंडित नहीं किया गया है, आसन्न छेदों को बड़े छेदों में शामिल करके, बहुत सामान्य है। अधिक गंभीर आवंटनकर्ता यह सुनिश्चित करने के लिए अधिक गंभीर तकनीकों का उपयोग करते हैं।

तो, मान लें कि आप तीन आवंटन और डी-आवंटन करते हैं और इस क्रम में मेमोरी में ब्लॉक किए गए हैं:

+-+-+-+
|A|B|C|
+-+-+-+

व्यक्तिगत आवंटन के आकार मायने नहीं रखते। फिर आप पहले और अंतिम एक, ए और सी को मुक्त करते हैं:

+-+-+-+
| |B| |
+-+-+-+

जब आप अंततः बी को मुक्त करते हैं, तो आप (शुरू में, कम से कम सिद्धांत में) के साथ समाप्त होते हैं:

+-+-+-+
| | | |
+-+-+-+

जिसे बस में विखंडित किया जा सकता है

+-+-+-+
|     |
+-+-+-+

यानी एक बड़ा मुक्त ब्लॉक, कोई अंश नहीं बचा।

अनुरोध के अनुसार संदर्भ:

  • Dlmalloc के लिए कोड पढ़ने का प्रयास करें । मैं एक बहुत अधिक उन्नत है, एक पूर्ण उत्पादन-गुणवत्ता कार्यान्वयन।
  • यहां तक ​​कि एम्बेडेड अनुप्रयोगों में, डी-टुकड़ाकरण कार्यान्वयन उपलब्ध हैं। उदाहरण के लिए FreeRTOS में कोड पर इन नोटों कोheap4.c देखें ।

1
क्या आप मुझे कुछ संदर्भ प्रदान कर सकते हैं?
निक

4
मुझे लगता है, यह ध्यान देने योग्य होगा कि वर्चुअल एड्रेस स्पेस भौतिक मेमोरी का प्रत्यक्ष प्रतिनिधित्व नहीं है। और भौतिक मेमोरी में विखंडन को ओएस द्वारा निपटाया जा सकता है, जबकि वर्चुअल मेमोरी को प्रक्रिया द्वारा जारी नहीं किया जाएगा या तो भौतिक रूप से जारी नहीं किया जाएगा।
लैपक

@PetrBudnik यह दुर्लभ होगा कि वर्चुअल मेमोरी मैप्स 1-1 से फिजिकल मेमोरी में कहीं भी हो, OS पेज मैपिंग में सोचेगा और कम से कम उपद्रव के साथ इसे अंदर और बाहर स्वैप करने में सक्षम होगा
शाफ़्ट

3
बहुत ही नटखट टिप्पणी: जबकि अवधारणा अच्छी तरह से समझाया गया है, वास्तविक उदाहरण थोड़ा चुना गया था .. अशुभ। Dlmalloc के स्रोत कोड को देखने और भ्रमित होने वाले किसी के लिए: किसी विशिष्ट आकार के नीचे ब्लॉक हमेशा 2 की शक्तियां होती हैं और तदनुसार विलय / विभाजित होती हैं। इसलिए हम एक 8-बाइट ब्लॉक और 1 4-बाइट ब्लॉक के साथ (संभवतः) समाप्त करेंगे, लेकिन कोई 12-बाइट ब्लॉक नहीं। कम से कम डेस्कटॉप पर आवंटनकर्ताओं के लिए यह एक सुंदर मानक दृष्टिकोण है, हालांकि शायद एम्बेडेड अनुप्रयोग अपने ओवरहेड के साथ अधिक सावधान रहने की कोशिश करते हैं।
वू

@ मैं उदाहरण में ब्लॉक के लिए एक आकार का उल्लेख हटा दिया, यह वैसे भी कोई फर्क नहीं पड़ा। बेहतर?
खोलना

42

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

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


6
+1 बिल्कुल। बात यह है कि, यदि freeप्रदर्शन पर प्रभाव डालने के लिए पर्याप्त समय कहा जा रहा है, तो संभवतः इसे पर्याप्त बार भी कहा जा रहा है जैसे कि इसे छोड़ना उपलब्ध स्मृति में बहुत बड़ा सेंध लगाएगा। एक एम्बेडेड सिस्टम पर स्थिति की कल्पना करना मुश्किल है, जहां प्रदर्शन लगातार पीड़ित होता है, freeलेकिन जहां mallocकेवल एक परिमित संख्या कहा जाता है; यह एक काफी दुर्लभ उपयोग मामला है जिसमें एक एम्बेडेड डिवाइस है जो डेटा की एक-शॉट प्रसंस्करण करता है फिर रीसेट करता है।
जेसन सी

10

यह कुल बकवास है, उदाहरण के लिए, कई अलग-अलग कार्यान्वयन हैं malloc, कुछ ने डग ली या इस तरह से ढेर को अधिक कुशल बनाने की कोशिश की


9

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

यह अभी भी निश्चित रूप से एक बुरा अभ्यास है (प्रदर्शन में सुधार हमेशा रूपरेखा पर आधारित होना चाहिए, अस्पष्ट आंत की भावना पर आधारित नहीं होना चाहिए), और यह कुछ ऐसा नहीं है जो आपको छात्रों को अन्य बाधाओं को समझाए बिना कहना चाहिए, लेकिन मैं बहुत सारे छोटे-पाइपिंग-शेल की कल्पना कर सकता हूं -इस तरह लिखा जाना (अगर एकमुश्त स्थैतिक आवंटन का उपयोग न करना)। यदि आप किसी ऐसी चीज पर काम कर रहे हैं जो आपके चरों को मुक्त नहीं करने से लाभान्वित होती है, तो आप या तो अत्यधिक कम विलंबता की स्थिति में काम कर रहे हैं (किस स्थिति में, आप डायनेमिक आवंटन और C ++? D) भी कैसे वहन कर सकते हैं, या आप कर रहे हैं? बहुत कुछ करना, बहुत गलत (जैसे कि एक पूर्णांक मेमोरी के एक ब्लॉक के बजाय एक हजार पूर्णांक आवंटित करके पूर्णांक सरणी आवंटित करना)।


ओएस को अंत में सब कुछ मुक्त करना केवल प्रदर्शन के बारे में नहीं है - इसे काम करने के लिए बहुत कम तर्क की भी आवश्यकता होती है।
ह्यूगोम

@ मिस्सिंगो दूसरे शब्दों में, यह आपको स्मृति प्रबंधन के कठिन होने के साथ दूर जाने देता है :) हालांकि, मैं देखूंगा कि गैर-प्रबंधित भाषाओं के खिलाफ एक तर्क के रूप में - यदि आपका कारण प्रदर्शन के बजाय जटिल मुक्त तर्क है, तो आप बेहतर हो सकते हैं एक ऐसी भाषा / वातावरण का उपयोग करना जो आपके लिए इसका ध्यान रखे।
लुआॅन

5

आपने उल्लेख किया कि वे इलेक्ट्रॉनिक्स प्रोफेसर थे। वे फर्मवेयर / रीयलटाइम सॉफ़्टवेयर लिखने के लिए उपयोग किए जा सकते हैं, सही समय पर सक्षम होने में सक्षम होने के कारण कुछ समय के लिए निष्पादन की आवश्यकता होती है। उन मामलों में जो आपको जानते हैं कि सभी आवंटन के लिए पर्याप्त मेमोरी है और मेमोरी को खाली नहीं करना और पुनः लोड करना निष्पादन के समय के लिए अधिक आसानी से गणना की गई सीमा दे सकता है।

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


10
ये एक अच्छा बिंदु है। हालाँकि, मुझे उम्मीद है कि वे mallocउस मामले में और ऐसे सभी का उपयोग नहीं करेंगे , बजाय स्थैतिक आवंटन (या शायद एक बड़ा हिस्सा आवंटित करते हैं और फिर मैन्युअल रूप से मेमोरी को संभालते हैं)।
लुआं

2

पिछले टिप्पणीकारों और उत्तरों की तुलना में एक अलग कोण से इसे लेने पर, एक संभावना यह है कि आपके प्रोफेसरों को उन प्रणालियों के साथ अनुभव हुआ है जहां स्मृति को सांख्यिकीय रूप से आवंटित किया गया था (अर्थात: जब कार्यक्रम संकलित किया गया था)।

जब आप कुछ करते हैं तो स्थैतिक आवंटन आता है:

define MAX_SIZE 32
int array[MAX_SIZE];

कई वास्तविक समय और एम्बेडेड सिस्टम (जो ईईएस या सीईएस द्वारा सामना किए जाने की सबसे अधिक संभावना है) में, आमतौर पर गतिशील मेमोरी आवंटन से पूरी तरह से बचना बेहतर होता है। तो, का उपयोग करता है malloc, newऔर उनके विलोपन समकक्ष दुर्लभ हैं। शीर्ष पर, हाल के वर्षों में कंप्यूटर में मेमोरी का विस्फोट हुआ है।

यदि आपके पास 512 एमबी उपलब्ध है, और आप सांख्यिकीय रूप से 1 एमबी आवंटित करते हैं, तो आपके सॉफ्टवेयर में विस्फोट होने से पहले आपके पास लगभग 511 एमबी ट्रैंडल होना चाहिए (ठीक है, बिल्कुल नहीं ... लेकिन मेरे साथ यहां जाएं)। मान लें कि आपके पास दुर्व्यवहार करने के लिए 511 एमबी है, अगर आप हर दूसरे को बिना मुक्त किए 4 सेकंड बाइट करते हैं, तो आप मेमोरी से बाहर निकलने से पहले लगभग 73 घंटे तक चल पाएंगे। दिन में एक बार बंद कई मशीनों को ध्यान में रखते हुए, इसका मतलब है कि आपका कार्यक्रम कभी भी स्मृति से बाहर नहीं होगा!

उपरोक्त उदाहरण में, रिसाव प्रति सेकंड 4 बाइट्स या 240 बाइट्स / मिनट है। अब कल्पना करें कि आप उस बाइट / मिनट अनुपात को कम करते हैं। वह अनुपात जितना कम होगा, आपका कार्यक्रम उतनी देर तक बिना किसी समस्या के चल सकता है। यदि आपका mallocअयोग्य है, तो यह एक वास्तविक संभावना है।

हेक, अगर आपको पता है कि आप केवल mallocएक बार कुछ करने जा रहे हैं , और वह mallocफिर कभी हिट नहीं होगा, तो यह स्थैतिक आवंटन की तरह है, हालांकि आपको यह पता करने की आवश्यकता नहीं है कि यह क्या है जो आप आवंटित कर रहे हैं- सामने। उदाहरण: मान लीजिए कि हमारे पास फिर से 512 एमबी है। हमें mallocपूर्णांकों के 32 सरणियों की आवश्यकता है । ये विशिष्ट पूर्णांक हैं - प्रत्येक में 4 बाइट्स। हम जानते हैं कि इन सरणियों का आकार 1024 पूर्णांकों से अधिक नहीं होगा। हमारे कार्यक्रम में कोई अन्य मेमोरी आवंटन नहीं होता है। क्या हमारे पास पर्याप्त स्मृति है? 32 * 1024 * 4 = 131,072। 128 केबी - तो हाँ। हमारे पास बहुत जगह है। यदि हम जानते हैं कि हम कभी भी अधिक मेमोरी आवंटित नहीं करेंगे, तो हम सुरक्षित रूप से कर सकते हैंmallocउन arrays उन्हें मुक्त करने के बिना। हालाँकि, इसका मतलब यह भी हो सकता है कि अगर आपका प्रोग्राम क्रैश हो जाता है तो आपको मशीन / डिवाइस को रिस्टार्ट करना होगा। यदि आप अपना प्रोग्राम 4,096 बार शुरू / बंद करते हैं तो आप सभी 512 एमबी आवंटित करेंगे। यदि आपके पास ज़ोंबी प्रक्रियाएं हैं, तो संभव है कि दुर्घटना के बाद भी स्मृति को मुक्त नहीं किया जाएगा।

अपने आप को दर्द और दुख से बचाएं, और इस मंत्र को द वन ट्रुथ के रूप में उपभोग करें: हमेशा एक के साथ जुड़ा mallocहोना चाहिए । हमेशा एक होना चाहिए । freenewdelete


2
अधिकांश एम्बेडेड और रियल-टाइम सिस्टम में, केवल 73 घंटों के बाद विफलता का कारण बनने वाला टाइम-बम एक गंभीर समस्या होगी।
बेन वोइगट

विशिष्ट पूर्णांक ??? इंटीगर कम से कम 16-बिट संख्या है और छोटे माइक्रोचिप्स पर आमतौर पर 16-बिट है। आम तौर पर sizeof(int)2 के बजाय 4 से अधिक डिवाइस होते हैं ।
ST3

2

मुझे लगता है कि प्रश्न में कहा गया दावा यदि प्रोग्रामर के दृष्टिकोण से शाब्दिक रूप से लिया गया है, तो यह बकवास है, लेकिन ऑपरेटिंग सिस्टम के दृष्टिकोण से इसमें सच्चाई (कम से कम कुछ) है।

malloc () अंततः mmap () या sbrk () को कॉल करेगा जो OS से एक पेज लाएगा।

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


2

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

पूरे तृतीय-पक्ष पुस्तकालय हैं, जो आपके लिए उस तरह की चीज़ के अलावा कुछ भी नहीं करते हैं, और कभी-कभी स्वीकार्य प्रदर्शन और कुछ ऐसा होता है जो बहुत धीरे-धीरे चलता है। malloc()और free()निष्पादित करने के लिए ध्यान देने योग्य समय लें, जिसे आप नोटिस करना शुरू करेंगे यदि आप उन्हें बहुत बुला रहे हैं।

इसलिए केवल भोलेपन से बचने से malloc()और free()आप विखंडन और प्रदर्शन दोनों समस्याओं से बच सकते हैं - लेकिन जब आप इसके ठीक नीचे हो जाते हैं, तो आपको हमेशा आपको free()सब कुछ सुनिश्चित करना चाहिए malloc()जब तक कि आपके पास अन्यथा करने के लिए बहुत अच्छा कारण न हो। आंतरिक मेमोरी पूल का उपयोग करते समय भी एक अच्छा अनुप्रयोग free()पूल मेमोरी को बाहर निकलने से पहले करेगा। हां, OS इसे साफ कर देगा, लेकिन अगर बाद में एप्लिकेशन जीवनचक्र बदल जाता है तो उस पूल को भूल जाना आसान होगा ...

पाठ्यक्रम के लंबे समय तक चलने वाले अनुप्रयोगों को उनके द्वारा आवंटित किए गए सब कुछ को साफ करने या पुनर्चक्रण करने के बारे में पूरी तरह से जांच करने की आवश्यकता है, या वे स्मृति से बाहर चल रहे हैं।


1

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

कुछ कार्यक्रम अच्छी तरह से व्यवहार करते हैं। वे तरंगों में स्मृति आवंटित करते हैं: बहुत सारे छोटे या मध्यम आकार के आवंटन, जिसके बाद बहुत सी मुक्तियां होती हैं, चक्रों को दोहराते हुए। इन कार्यक्रमों में विशिष्ट मेमोरी एलोकेटर्स अच्छी तरह से करते हैं। वे मुक्त ब्लॉकों को समेटते हैं और एक लहर के अंत में अधिकांश मुक्त स्मृति बड़े सन्निहित चक्रों में होती है। ये कार्यक्रम काफी दुर्लभ हैं।

अधिकांश कार्यक्रम बुरी तरह से व्यवहार करते हैं। वे बहुत कम से लेकर बहुत बड़े आकार में विभिन्न प्रकार के आकारों में अधिक या कम बेतरतीब ढंग से मेमोरी को आवंटित और डील करते हैं, और वे आवंटित ब्लॉकों के उच्च उपयोग को बनाए रखते हैं। इन कार्यक्रमों में ब्लॉक को समतल करने की क्षमता सीमित होती है और समय के साथ वे उच्च खंडित और अपेक्षाकृत गैर-सन्निहित स्मृति के साथ समाप्त हो जाते हैं। यदि कुल मेमोरी का उपयोग 32-बिट मेमोरी स्पेस में लगभग 1.5GB से अधिक है, और 10MB या उससे अधिक के आवंटन हैं, तो अंततः बड़े आवंटन में से एक विफल हो जाएगा। ये कार्यक्रम आम हैं।

अन्य कार्यक्रम मुफ्त या कम मेमोरी नहीं देते हैं, जब तक कि वे बंद न हो जाएं। वे क्रमिक रूप से मेमोरी को आवंटित करते हैं, जबकि केवल छोटी मात्रा को मुक्त करते हैं, और फिर बंद हो जाते हैं, जिस समय सभी मेमोरी को मुक्त कर दिया जाता है। एक कंपाइलर इस तरह है। तो एक वी.एम. उदाहरण के लिए, .NET CLR रनटाइम, जो स्वयं C ++ में लिखा गया है, शायद कभी भी किसी भी मेमोरी को मुक्त नहीं करता है। क्यों करना चाहिए?

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

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

संपादित करें

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

मैं अपना मुख्य संदेश दोहराऊंगा: वास्तविक कार्यक्रमों में बड़े पैमाने पर स्मृति आवंटन के लिए मॉलोक और मुफ्त संतुलन पर्याप्त उपाय नहीं है। ब्लॉक कोलेसिंग सामान्य है, और समय खरीदता है, लेकिन यह पर्याप्त नहीं है। आपको गंभीर, चतुर मेमोरी एलोकेटर की आवश्यकता होती है, जो मेमोरी को चंक्स (मॉलोक या जो कुछ भी) का उपयोग करके हड़पते हैं और शायद ही कभी मुक्त होते हैं। शायद यही संदेश ओपी के प्रोफेसरों के दिमाग में था, जिसे उन्होंने गलत समझा।


1
खराब व्यवहार करने वाले कार्यक्रमों से पता चलता है कि सभ्य आबंटकों को अलग-अलग आकार के टुकड़ों के लिए अलग-अलग पूल का उपयोग करना चाहिए। वर्चुअल मेमोरी के साथ, कई अलग-अलग पूलों को दूर रखना एक बड़ी समस्या नहीं होनी चाहिए। यदि प्रत्येक चंक्स को दो की शक्ति तक गोल किया जाता है, और प्रत्येक पूल में केवल एक आकार के गोल टुकड़े होते हैं, तो मैं यह नहीं देख सकता कि कैसे विखंडन कभी भी बहुत खराब हो सकता है। सबसे बुरी तरह से एक कार्यक्रम अचानक एक निश्चित आकार सीमा में पूरी तरह से दिलचस्पी लेना बंद कर सकता है, अप्रयुक्त रहने के लिए कुछ हद तक खाली पूल छोड़ सकता है; मुझे नहीं लगता कि यह बहुत सामान्य व्यवहार है।
मार्क वैन लीउवेन

5
दावे के लिए प्रशस्ति पत्र की बहुत आवश्यकता है कि सक्षम रूप से लिखे गए प्रोग्राम ऐप को बंद होने तक मेमोरी को मुक्त नहीं करते हैं।

12
यह पूरा उत्तर यादृच्छिक अनुमानों और दमन की एक श्रृंखला की तरह पढ़ता है। क्या इसमें से कुछ भी वापस करना है?
क्रिस हेस

4
मुझे यकीन नहीं है कि आपके कहने का मतलब क्या है कि .NET CLR रनटाइम किसी भी मेमोरी को मुक्त नहीं करता है। जहां तक ​​मैंने परीक्षण किया है, अगर यह हो सकता है।
थियोडोरोस चटजिआनियाकिस

1
@vonbrand: GCC के पास कई आवंटन हैं, जिसमें कचरा कलेक्टर का अपना ब्रांड भी शामिल है। यह पास के दौरान मेमोरी की खपत करता है, और इसे पास के बीच इकट्ठा करता है। अन्य भाषाओं के अधिकांश कंपाइलरों में अधिकतम 2 पास होते हैं और पास के बीच मुफ्त या कम मेमोरी नहीं होती है। यदि आप असहमत हैं, तो मुझे आपके द्वारा दिए गए किसी भी उदाहरण पर शोध करने में खुशी होगी।
david.pfx

1

मुझे आश्चर्य है कि किसी ने भी पुस्तक को उद्धृत नहीं किया है:

यह अंततः सच नहीं हो सकता है, क्योंकि यादें बहुत बड़ी हो सकती हैं ताकि कंप्यूटर के जीवनकाल में मुफ्त मेमोरी से बाहर निकलना असंभव हो। उदाहरण के लिए, एक वर्ष में लगभग 3 13 10 13 माइक्रोसेकंड होते हैं, इसलिए यदि हम माइक्रोसेकंड के अनुसार एक बार विपक्ष में थे, तो हमें एक मशीन बनाने के लिए लगभग 10 15 कोशिकाओं की स्मृति की आवश्यकता होगी जो 30 साल तक मेमोरी से बाहर चलने के बिना काम कर सकती है। यह बहुत याददाश्त आज के मानकों से बेतुका है, लेकिन यह शारीरिक रूप से असंभव नहीं है। दूसरी ओर, प्रोसेसर तेज़ हो रहे हैं और भविष्य के कंप्यूटर में बड़ी संख्या में प्रोसेसर एकल मेमोरी पर समानांतर में चल सकते हैं, इसलिए संभव है कि हम पोस्ट किए गए मेमोरी की तुलना में बहुत तेज़ी से मेमोरी का उपयोग करें।

http://sarabander.github.io/sicp/html/5_002e3.xhtml#FOOT298

तो, वास्तव में, कई कार्यक्रम किसी भी स्मृति को मुक्त करने के लिए परेशान किए बिना बस ठीक कर सकते हैं।


1

मुझे एक मामले के बारे में पता है जब स्पष्ट रूप से मुक्त करने वाली मेमोरी बेकार से भी बदतर है । यही है, जब आपको प्रक्रिया के अंत तक आपके सभी डेटा की आवश्यकता होती है । दूसरे शब्दों में, जब उन्हें समाप्त करना कार्यक्रम समाप्ति से ठीक पहले संभव है। चूँकि कोई भी आधुनिक OS किसी प्रोग्राम के मर जाने पर फ्री मेमोरी को ध्यान में रखता है, तो free()उस स्थिति में कॉल करना आवश्यक नहीं है। वास्तव में, यह कार्यक्रम समाप्ति को धीमा कर सकता है, क्योंकि इसे मेमोरी में कई पृष्ठों तक पहुंचने की आवश्यकता हो सकती है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.