दिलचस्प पोस्ट
रेल में, आप एक दृश्य का उपयोग करके JSON को कैसे प्रस्तुत करते हैं? क्या एक जावास्क्रिप्ट अगर कई स्थितियों के साथ बयान उन सभी का परीक्षण करते हैं? दो तालिकाओं का संयोजन करें जिनमें कोई सामान्य फ़ील्ड नहीं है आर में एक उपयोगी डेटा फ्रेम में विभिन्न लंबाई के सदिश की सूची को कैसे परिवर्तित करें? जब हम मैक्रो को परिभाषित करते हैं तो करते समय (0) का क्या उपयोग होता है? डाउनलोड करने के लिए जेएसपी एक्सेल स्प्रैडशीट (एक्सएलएस) पैदा कर रहा है बिटवे ऑपरेशन और उपयोग दिए गए url से डोमेन नाम प्राप्त करें उपयोग किए गए हेडरों को ढूंढने के लिए उपकरण जो अप्रयुक्त हैं? PHP और fgetcsv फ़ंक्शन का उपयोग करते हुए सीएसवी फ़ाइल से एक सरणी कैसे बनाएं जावा में स्थैतिक ब्लॉक निष्पादित नहीं है Nested टुकड़ा (एंड्रॉइड 4.2) का उपयोग करते हुए एक दृश्यपेज के अंदर एक टुकड़ा कैसे जोड़ें इंटरनेट कनेक्टिविटी राज्य परिवर्तन के लिए एंड्रॉइड इवेंट नेस्टेड जेएसओएन डेटा तक कैसे पहुंचें Android में कस्टम टाइपफ़ेस का उपयोग करना

क्या मॉलोक कार्यान्वयन सिस्टम को फ्री-एड मेमोरी वापस देगा?

मेरे पास लगातार मेमोरी आवंटन-डेलोकेशन के साथ लंबे समय तक रहने वाला आवेदन है। क्या किसी भी malloc कार्यान्वयन रिटर्न प्रणाली को वापस स्मृति मुक्त?

क्या है, इस संबंध में, का व्यवहार:

  • ptmalloc 1, 2 (glibc डिफ़ॉल्ट) या 3
  • dlmalloc
  • टीसीएमएलएलओक (गूगल थ्रेड मॉलोक)
  • सौर 10-11 डिफ़ॉल्ट मैलोक और एमटीएमएलएलओक
  • फ्री बीएसडी 8 डिफ़ॉल्ट मॉलोक (जेमॉलोक)
  • होर्ड मॉलोक?

अद्यतन करें

अगर मेरे पास एक ऐसा एप्लिकेशन है जिसकी स्मृति की खपत दिन-रात और रात्रि में बहुत भिन्न हो सकती है (उदाहरण के लिए), क्या मैं किसी भी malloc को सिस्टम को मुक्त स्मृति वापस करने के लिए मजबूर कर सकता हूं?

इस तरह के रिटर्न के बिना मुक्त स्मृति को स्वैप किया जाएगा और कई बार, लेकिन ऐसी मेमोरी में केवल कचरा होता है।

वेब के समाधान से एकत्रित समाधान "क्या मॉलोक कार्यान्वयन सिस्टम को फ्री-एड मेमोरी वापस देगा?"

निम्नलिखित विश्लेषण केवल glibc पर लागू होता है (ptmalloc2 एल्गोरिदम पर आधारित)। कुछ विकल्प हैं जो मुक्त स्मृति को सिस्टम पर वापस लौटने में मददगार लगते हैं:

  1. mallopt () ( malloc.h में परिभाषित) पैरामीटर विकल्प M_TRIM_THRESHOLD में से एक का उपयोग करके ट्रिम थ्रेशोल्ड मान को सेट करने के लिए एक विकल्प प्रदान करता है, यह डेटा सेगमेंट के शीर्ष पर अनुमत मुफ्त मेमोरी (बाइट्स में) की न्यूनतम राशि इंगित करता है यदि राशि इस दहलीज से नीचे आती है, तो glibc कर्नेल को स्मृति को वापस देने के लिए brk() को आमंत्रित करता है।

    लिनक्स में M_TRIM_THRESHOLD का डिफ़ॉल्ट मान 128K पर सेट किया गया है, एक छोटे मूल्य सेट करने से अंतरिक्ष बचा सकता है।

    पर्यावरण MALLOC_TRIM_THRESHOLD_ में ट्रिम थ्रेशोल्ड मान को सेट करके ही व्यवहार प्राप्त किया जा सकता है, बिना कोई स्रोत परिवर्तन बिल्कुल।

    हालांकि, M_TRIM_THRESHOLD का उपयोग करते हुए प्रारंभिक परीक्षण कार्यक्रमों ने दिखाया है कि भले ही malloc द्वारा आवंटित स्मृति सिस्टम पर वापस आती है, तो स्मृति के वास्तविक हिस्से का शेष भाग (एरेना) प्रारंभ में brk() के माध्यम से अनुरोध किया जाता है, उसे बनाए रखा जाता है

  2. मेमोरी क्षेत्र ट्रिम करना और malloc_trim(pad) ( malloc.h में परिभाषित malloc_trim(pad) को कॉल करके सिस्टम को किसी भी अप्रयुक्त स्मृति को वापस करना malloc.h । यह फ़ंक्शन डेटा सेगमेंट का आकार बदलता है, इसके अंत में कम से कम pad बाइट्स को छोड़कर और बाइट के एक से कम पृष्ठ को मुक्त किया जा सकता है। सेगमेंट का आकार हमेशा एक पृष्ठ का एक बहुमान होता है, जो i386 पर 4,0 9 6 बाइट्स है।

    malloc_trim का उपयोग कर free() के इस संशोधित व्यवहार के लिए क्रियान्वयन malloc_trim हुक कार्यक्षमता का उपयोग करके किया जा सकता है इसके लिए कोर ग्लिब पुस्तकालय में कोई स्रोत कोड बदलाव की आवश्यकता नहीं होगी।

  3. madvise() प्रणाली का उपयोग कर glibc के नि: शुल्क कार्यान्वयन के अंदर कॉल करें

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

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

ज्यादातर सिस्टम ओपन बीएसडी के रूप में सुरक्षा-केंद्रित नहीं हैं, हालांकि।

यह जानने के बाद, जब मैं लंबे समय से चलने वाली एक प्रणाली को लिख रहा हूँ जिसमें बड़ी मात्रा में मेमोरी के लिए ज्ञात-टू-ट्रांसिटरी आवश्यकता होती है, तो मैं हमेशा प्रक्रिया fork करने की कोशिश करता हूं: माता-पिता तब सिर्फ बच्चे के परिणामों की प्रतीक्षा करता है [ [आम तौर पर एक पाइप पर]], बच्चे की गणना (स्मृति आवंटन सहित) करता है, परिणाम [[कहा पाइप पर]] देता है, तो समाप्त होता है। इस तरह, मेरी लंबे समय से चलने वाली प्रक्रिया कभी-कभी मेमोरी के लिए अपनी मांग में "स्पाइक्स" के बीच लंबे समय के दौरान मेमोरी बेकार नहीं होगी। अन्य वैकल्पिक रणनीतियों में ऐसी विशेष आवश्यकताओं के लिए कस्टम मेमोरी आवंटन पर स्विच करना शामिल है (सी ++ यह काफी आसान बनाता है, हालांकि जावा और पायथन जैसी भाषाओं के साथ भाषाओं में आमतौर पर नहीं)।

मैं ओपी के समान समस्या से निपट रहा हूं। अब तक, यह संभव है टीसीएमएलएलक के साथ। मुझे दो समाधान मिले:

  1. tcmalloc से लिंक किए गए अपने प्रोग्राम को संकलित करें, फिर उसे इस रूप में लॉन्च करें:

     env TCMALLOC_RELEASE=100 ./my_pthread_soft 

    प्रलेखन में उल्लेख है कि

    उचित दर सीमा [0,10] में हैं

    लेकिन 10 मेरे लिए पर्याप्त नहीं लगता है (यानी मुझे कोई बदलाव नहीं है)

  2. अपने कोड में कहीं न कहीं खोजें जहां यह सभी मुक्त स्मृति को छोड़ना दिलचस्प होगा, और फिर यह कोड जोड़ें:

     #include "google/malloc_extension_c.h" // C include #include "google/malloc_extension.h" // C++ include /* ... */ MallocExtension_ReleaseFreeMemory(); 

दूसरा समाधान मेरे मामले में बहुत प्रभावी रहा है; पहले महान होगा लेकिन यह बहुत सफल नहीं है, उदाहरण के लिए सही संख्या को खोजने के लिए जटिल है।

सभी 'सामान्य' मॉलों के लिए, जिन लोगों का आपने उल्लेख किया है, उनमें भी आपकी प्रक्रिया से पुनः उपयोग करने के लिए स्मृति जारी की जाती है, लेकिन पूरे सिस्टम पर वापस नहीं। पूरे सिस्टम पर वापस आना तब होता है जब आप प्रक्रिया को समाप्त कर देते हैं।

जिन लोगों की आप सूची में हैं, केवल होर्ड सिस्टम को याद दिलाएगा … लेकिन अगर यह वास्तव में ऐसा कर सकता है तो आपके प्रोग्राम के आवंटन के व्यवहार पर बहुत निर्भर करेगा।

मेरे ऐप में एक ऐसी ही समस्या थी, कुछ जांच के बाद मैंने पाया कि किसी वजह से glibc मेमोरी को सिस्टम में वापस नहीं लौटा देता है जब आवंटित वस्तुएं छोटी हो जाती हैं (मेरे मामले में 120 बाइट्स से कम)।
इस कोड को देखें:

 #include <list> #include <malloc.h> template<size_t s> class x{char x[s];}; int main(int argc,char** argv){ typedef x<100> X; std::list<X> lx; for(size_t i = 0; i < 500000;++i){ lx.push_back(X()); } lx.clear(); malloc_stats(); return 0; } 

प्रोग्राम आउटपुट:

 Arena 0: system bytes = 64069632 in use bytes = 0 Total (incl. mmap): system bytes = 64069632 in use bytes = 0 max mmap regions = 0 max mmap bytes = 0 

लगभग 64 एमबी सिस्टम पर वापस नहीं आए हैं। जब मैं typedef को बदल दिया: typedef x<110> X; प्रोग्राम आउटपुट इस तरह दिखता है:

 Arena 0: system bytes = 135168 in use bytes = 0 Total (incl. mmap): system bytes = 135168 in use bytes = 0 max mmap regions = 0 max mmap bytes = 0 

लगभग सभी स्मृति मुक्त हो गई थी मैंने यह भी पाया है कि malloc_trim(0) का उपयोग किसी भी मामले में प्रणाली को स्मृति में जारी किया जाता है।
उपरोक्त कोड में malloc_trim जोड़ने के बाद यहां उत्पादन किया गया है:

 Arena 0: system bytes = 4096 in use bytes = 0 Total (incl. mmap): system bytes = 4096 in use bytes = 0 max mmap regions = 0 max mmap bytes = 0 

संक्षिप्त उत्तर: मेल्लोक सबसिस्टम को ओएस पर मेमोरी देने के लिए मजबूर करने के लिए, malloc_trim () का उपयोग करें। अन्यथा, वापस लौटने का व्यवहार कार्यान्वयन निर्भर है।