2009-04-20 4 views
6

में मेमोरी लीक मैं एक इंटेल एक्सस्केल डिवाइस पर अपना सी ++ एप्लिकेशन चला रहा हूं। समस्या यह है कि, जब मैं Valgrind के साथ अपना एप्लिकेशन ऑफटेक्चर (उबंटू) चलाता हूं, तो यह कोई मेमोरी लीक नहीं दिखाता है।सी ++

लेकिन जब मैं इसे लक्ष्य प्रणाली पर चलाता हूं, तो यह 50K मुफ्त मेमोरी से शुरू होता है, और 2K रातोंरात कम हो जाता है। इस तरह के रिसाव को कैसे पकड़ें, जिसे वालग्रिंड द्वारा नहीं दिखाया जा रहा है?

+0

क्या आपके पास कोई कोड है जो अलग है? क्या यह वास्तव में समान है? यदि अंतर नहीं है तो क्या अंतर है। बस कुछ त्वरित विचार। –

+0

मुझे लगता है कि आपका मतलब है: 50 केबी * मुफ्त * से शुरू होता है? – MSalters

+0

हां, यह 50 केबी के साथ शुरू होता है। हां, कुछ मंच विशिष्ट कोड भी हैं। लेकिन, मैंने इसे लक्ष्यीकरण प्रणाली पर चलाते समय अक्षम कर दिया। लेकिन, अभी भी एक ही मुद्दा है। – Ajay

उत्तर

3

यह वास्तविक स्मृति रिसाव नहीं हो सकता है, लेकिन शायद स्मृति उपयोग में वृद्धि की स्थिति हो सकती है। उदाहरण के लिए यह एक लगातार बढ़ती स्ट्रिंग का आवंटन किया जा सकता है:

string s; 
for (i=0; i<n; i++) 
    s += "a"; 

50 कि ज्यादा नहीं है, हो सकता है आप हाथ से अपने स्रोत से अधिक जाना है और क्या कारण समस्या हो सकती देखना चाहिए।

+0

अच्छा, वास्तव में यह 50 के मेमोरी फ्री के साथ शुरू होता है और 2 के मेमोरी मुक्त के साथ समाप्त होता है। कोड लगभग 1,00,000 लाइनों का है। – Ajay

+0

वैसे यह केवल 48 केबी लीक है, यह कहने के लिए खेद है कि यह वास्तविक रिसाव नहीं है, आपको संभावित अपराधियों के लिए कोड खोजना पड़ सकता है ... स्मृति आवंटन लॉगिंग के बारे में कैसे? –

+0

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

3

यह एक रिसाव नहीं हो सकता है, लेकिन केवल रनटाइम ढेर ऑपरेटिंग सिस्टम को स्मृति जारी नहीं कर रहा है। यह विखंडन भी हो सकता है। इस पर काबू पाने के लिए

संभव तरीके: दो आवेदनों में

  1. स्प्लिट। मास्टर एप्लिकेशन में सरल या तर्कसंगत स्मृति उपयोग के साथ सरल तर्क होगा। यह कार्यकर्ता अनुप्रयोग को वास्तव में इस तरह के कार्यों में काम करने के लिए शुरू करेगा कि कार्यकर्ता आवेदन स्मृति से बाहर नहीं होगा और समय-समय पर उस एप्लिकेशन को पुनरारंभ करेगा। इस तरह स्मृति समय-समय पर ऑपरेटिंग सिस्टम में लौटा दी जाती है।

  2. अपना खुद का मेमोरी आवंटक लिखें। उदाहरण के लिए आप एक समर्पित ढेर आवंटित कर सकते हैं और केवल वहां से स्मृति आवंटित कर सकते हैं, फिर समर्पित ढेर को पूरी तरह से मुक्त कर सकते हैं। इसके लिए ऑपरेटिंग सिस्टम को एकाधिक ढेर का समर्थन करने की आवश्यकता होती है।

भी ध्यान रखें कि यह है कि अपने कार्यक्रम Ubuntu पर और लक्ष्य सिस्टम पर अलग ढंग से चलाता है और इसलिए अलग निष्पादन रास्तों लिया जाता है और मेमोरी लीक में जिसके परिणामस्वरूप कोड लक्ष्य सिस्टम पर निष्पादित किया जाता है, लेकिन Ubuntu पर नहीं संभव है।

+0

लेकिन, क्या होता है, Xscale डिवाइस, एक बिंदु पर, स्मृति से बाहर चला जाता है और फिर एप्लिकेशन क्रैश हो जाता है। इसलिए, स्मृति की निरंतर मात्रा को रोकने के लिए जरूरी है। क्या आप कृपया कुछ रास्ता सुझा सकते हैं? – Ajay

0

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

मैं जो भी जोड़ सकता हूं वह है कि वालग्रिंड मेमोरी लीक खोजने में काफी कुशल माना जाता है!

0

इसके अलावा, क्या आप सुनिश्चित हैं कि आपने अपना कोड प्रोफाइल करते समय कोड-कवरेज उन सभी कोड-पथ को कवर करने के लिए पर्याप्त था जो लक्ष्य प्लेटफ़ॉर्म पर निष्पादित किए जा सकते हैं?

निश्चित रूप से वालग झूठ नहीं बोलता है। जैसा कि बताया गया है, यह वास्तव में रनटाइम ढेर हो सकता है जो स्मृति को जारी नहीं करता है, लेकिन मैं अन्यथा सोचता हूं।

0

क्या आप ऑब्जेक्ट के दायरे को ट्रैक करने के लिए किसी भी परिष्कृत तकनीक का उपयोग कर रहे हैं ..? यदि हाँ, की तुलना में valgrind स्मार्ट पर्याप्त नहीं है, हालांकि आप

+0

मैं valgrind में किसी भी xscale संबंधित विकल्पों से अनजान हूँ। उसको कैसे करे? – Ajay

0

अधिकांश आवेदनों की इस तरह स्मृति उपयोग की ओर इशारा दिखाने valgrind साथ X स्केल संबंधित विकल्प सेट करके की कोशिश कर सकते हैं:

  • वे बहुत कम है, जब वे शुरू का उपयोग
  • के रूप में वे डेटा संरचना बनाने के वे अधिक से अधिक
  • के रूप में वे पुराने डेटा संरचनाओं को हटाने या मौजूदा पुन: उपयोग शुरू करते हैं, वे एक स्थिर अवस्था तक पहुँचने स्मृति उपयोग मोटे तौर पर लगातार
रहता है जहां का उपयोग

यदि आपका ऐप आकार में लगातार बढ़ रहा है, तो आप अलेक हो सकते हैं। यदि यह एपिरियोड पर सिज़े में बढ़ता है और फिर स्थिर रूप से स्थिर स्थिति तक पहुंच जाता है, तो शायद आप नहीं करते हैं।

10

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

1

यह एक विखंडन की तरह लगता है। विखंडन आप ढेर पर वस्तुओं का आवंटन के कारण होता है, कहते हैं:

object1
object2
object3
object4

और फिर कुछ वस्तुओं

object1

object3
object4

को हटाने

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

इसके आसपास का तरीका आपकी स्मृति आवश्यकताओं को आगे बढ़ाने और तय करने का तरीका है। यदि आपके पास विशेष वस्तुएं हैं जो आप जानते हैं कि आप कई बना रहे हैं, तो कोशिश करें और सुनिश्चित करें कि वे एक ही आकार के हैं।

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

ऐसा करने का एक तरीका यह एक भी स्थिर बनाने के लिए है:

struct Slot 
{ 
    Slot() : free(true) {} 
    bool free; 
    BYTE data[20]; // you'll need to tune the value 20 to what your program needs 
}; 
Slot pool[500]; // you'll need to pick a good pool size too. 

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

फिर नए को ओवरराइड करें और एक संदिग्ध वर्ग के लिए ऑपरेटर हटाएं ताकि वे इस वेक्टर से स्लॉट वापस कर सकें। तो, आपकी वस्तुएं इस वेक्टर में संग्रहित की जाएंगी।

आप इस वेक्टर में एक ही आकार के वर्गों के लिए नए ओवरराइड कर सकते हैं और हटा सकते हैं।

विभिन्न वस्तुओं के लिए विभिन्न आकारों के पूल बनाएं।

बस सबसे खराब अपराधी के लिए जाएं।

मैंने पहले ऐसा कुछ किया है और यह एक एम्बेडेड डिवाइस पर मेरी समस्या हल कर चुका है। मैं भी बहुत सारे एसटीएल का उपयोग कर रहा था, इसलिए मैंने एक कस्टम आवंटक बनाया (एसएलएल कस्टम आवंटक के लिए Google - लिंक के भार हैं)। यह मेरे प्रोग्राम का उपयोग किए गए मिनी-डेटाबेस में संग्रहीत रिकॉर्ड्स के लिए उपयोगी था।

0

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