2013-07-26 17 views
6

से बाहर स्मृति को साफ़ नहीं करता है मुझे निम्नलिखित समस्या का सामना करना पड़ा है, और मुझे सच में यकीन नहीं है कि मैं गलत हूं या यह वास्तव में अजीब बग है। मैं तारों की एक विशाल सरणी भरता हूं और इसे एक निश्चित बिंदु पर साफ़ करना चाहता हूं। यहाँ एक न्यूनतम उदाहरणवेक्टर <string> स्कोप

#include <string> 
#include <vector> 
#include <unistd.h> //sleep 
#include <iostream> 

int main(){ 
    { 
     std::vector<std::string> strvec; 
     for(long i = 0; i < 1000000; ++i){ 
      std::string out = "This is gonna be a long string just to fill up the memory used by this fucking pthread\n"; 
      strvec.push_back(out); 
     } 
     std::cout << "finished loading 1st\n"; 
     sleep(10); // to monitor any changes  
    } 
    std::cout << "out of scope\n"; 
    sleep(10); 
    return 0; 
} 

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

std :: वेक्टर संदर्भ राज्य, कि, यदि निहित मान कोई पॉइंटर्स नहीं हैं, तो विनाशकों को बुलाया जाता है। स्ट्रिंग के लिए सच नहीं लगता है ...

मैं हर उत्तर की सराहना करता हूं।

धन्यवाद जवाब के लिए अब तक::

संपादित करें (सुविधा के लिए मैं ++ जी के साथ 4.7.2 डेबियन लिनक्स 64 बिट का उपयोग कर रहा हूँ)।

अब तक मैंने योनि मासफ के साथ ढेर का उपयोग किया है, और (हाँ, वास्तव में अपेक्षित) यह उस बिंदु पर ठीक से मुक्त हो जाता है। लेकिन मैं वास्तव में एक विशाल पूर्णांक के साथ उपयोग में परिवर्तन क्यों देखता हूं, लेकिन तारों के साथ नहीं (शीर्ष पर भी)?

मुझे इसके बारे में थोड़ा सा विचार करने की आवश्यकता है, क्योंकि मुझे मल्टीथ्रेडेड सर्वर एप्लिकेशन के लिए कुछ समय पर अपनी याददाश्त मुक्त करने में सक्षम होना चाहिए, जो संभवतः बिना किसी पुनरारंभ किए कई सप्ताह या अधिक चलाएगा। मुझे वास्तव में कब पता चलेगा कि सी ++ मेमोरी मैनेजर ओएस को वापस कुछ याद करने का फैसला करता है?

+0

[valgrind] (http://valgrind.org/) के साथ डिबगिंग करने का प्रयास करें यह आपको बताएगा कि स्मृति मुक्त है या नहीं, और शायद 'शीर्ष' से अधिक सहायक होगी। – Couchy311

+0

लोगों के आग्रह के साथ यह क्या है कि स्मृति बर्बाद हो जाती है? मुफ्त मेमोरी * कुछ नहीं * - यह स्मृति से बेहतर नहीं है जो कंप्यूटर में बिल्कुल नहीं है। उपयोग में * केवल स्मृति * कोई अच्छा है। –

उत्तर

6

यह top कमांड का उपयोग करने का एक विशिष्ट है, std::vector का नहीं। मुद्दा यह है कि डेटा संरचनाओं से मुक्त स्मृति को ऑपरेटिंग सिस्टम पर वापस नहीं छोड़ा जाता है, जिस स्तर पर top कमांड स्मृति उपयोग पर नज़र रखता है। ओएस ने आपके प्रोग्राम को आपके प्रोग्राम के साथ याद किया है जब तक कि सी ++ के मेमोरी मैनेजर का फैसला नहीं होता कि अब कुछ मेमोरी ऑपरेटिंग सिस्टम पर मुक्त करने का समय है।

इसका कारण यह है कि ऑपरेटिंग सिस्टम से स्मृति आवंटित करना अपेक्षाकृत महंगा है, और इसे अपेक्षाकृत बड़े हिस्सों में किया जाना चाहिए। सी ++ रनटाइम लाइब्रेरी का मेमोरी मैनेजर ओएस "थोक" से मेमोरी प्राप्त करता है, और उसके बाद इसे आवश्यकतानुसार आपके प्रोग्राम के हिस्सों में पार्सल करता है।

यदि आप यह सत्यापित करना चाहते हैं कि स्मृति वास्तव में पुनः प्राप्त की जाती है, तो उस उपकरण का उपयोग करें जो कम स्तर पर स्मृति उपयोग पर नज़र रखता है, जैसे valgrind

4

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

उदाहरण के लिए, जब आप पहली बार स्मृति के सभी आवंटन, पुस्तकालय आभासी स्मृति पता स्थान का एक समूह ओएस (mmap(2) साथ होने की संभावना) से आवंटित करता है और यह बाहर खैरात। लेकिन जब आप उस स्मृति के साथ काम करते हैं, तो यह धारणा के तहत वर्चुअल एड्रेस स्पेस पर लटकता है कि आप उस मेमोरी को बाद में वापस ले सकते हैं, इसलिए यह वर्चुअल एड्रेस स्पेस को अनमैप करने के लिए munmap(2) पर कॉल नहीं करता है।

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

0

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

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