2013-02-06 47 views
10

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

एक त्वरित परीक्षण से पता चलता है कि जब विज़ुअल सी में ++ 2010 सी ++ अपवाद अक्षम करने (यानी कोई/EHA,/EHsc या/EHS झंडे), यह अभी भी एक पकड़ (std :: bad_alloc &) ब्लॉक करने के लिए कूदता है जब बहुत अधिक स्मृति का आवंटन ।

तो ऐसा लगता है कि वांछित काम करता है। हालांकि, मुझे निम्न स्तर 1 चेतावनी मिलती है: "सी 4530: सी ++ अपवाद हैंडलर का उपयोग किया जाता है, लेकिन सेमेन्टिक्स को खोलने में सक्षम नहीं हैं। निर्दिष्ट करें/EHsc"। एमएसडीएन का कहना है कि "फ्रेम में स्वचालित भंडारण वाला एक वस्तु, फेंकने वाले समारोह और फेंकने वाले समारोह के बीच, नष्ट नहीं किया जाएगा"।

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

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

आपकी सलाह के लिए धन्यवाद।

+0

* क्या डीएलएल एक अलग मेमोरी पूल का उपयोग करते हैं? * Http://stackoverflow.com/questions/10820114/do-statically-linked-dlls-use-a- अलग-heap-than-the-main-program – thang

+0

* और यदि हां, तो क्या मैं इसे डीएलएल को उतारने के लिए आवेदन की आवश्यकता के बिना शुद्ध कर सकता हूं? * हाँ, बस नए से सामान हटाएं और सामान को मॉलोक से मुक्त करें। – thang

+1

अपवाद हैंडलिंग का मतलब यह नहीं है कि ढेर पर बनाए गए ऑब्जेक्ट्स (और एक निर्माता जो विफल रहता है) नष्ट नहीं किया जाएगा। यदि आप 'bad_alloc' होने पर बाहर निकलने जा रहे हैं, तो आप इसके साथ ठीक हैं, मुझे लगता है [जब तक आपके पास अजीब संसाधन नहीं होते हैं जो प्रोग्राम से बाहर निकलते नहीं हैं - लेकिन सबसे अधिक चाहिए]। यदि आप 'bad_alloc' के बाद "जारी रखना" चाहते हैं, तो कोड को ऑब्जेक्ट को ट्रैक करने और' फेंक 'और' पकड़ 'के बीच ढेर फ्रेम में बनाए गए सभी ऑब्जेक्ट को नष्ट करने की आवश्यकता होगी। आप कुछ छोटे कोड लिखकर प्रयोग कर सकते हैं जिनमें विनाशकों में प्रिंटआउट हैं। –

उत्तर

1

कुछ प्रारंभिक तैयारियाँ:

यदि अपवाद हैंडलिंग के बिना एक अपवाद फेंक सक्षम मैं नहीं जानता कि अपरिभाषित व्यवहार या नहीं मानक से है, लेकिन आप निश्चित रूप से अपने वस्तुओं से तनाव मुक्त होने के/नाशक कॉल ढेर पाने के लिए नहीं जा रहे हैं ढेर पर

यदि आप म्यूटेक्स, फाइल, मेमोरी इत्यादि के लिए आरएआईआई का उपयोग कर सी ++ स्टाइल कोड लिख रहे हैं, तो यह एक बहुत ही खराब बात है।

1) आप स्थिर सी क्रम पुस्तकालय को जोड़ने रहे हैं, तो अपने DLL अपने मुख्य आवेदन के साथ एक ढेर साझा नहीं करेंगे:

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

2) यदि आप गतिशील रूप से सी रनटाइम (काफी आम) से लिंक कर रहे हैं, तो आप एक ढेर साझा कर रहे हैं। आपको DLL से आवंटित किसी भी स्मृति को मैन्युअल रूप से रिलीज़ करने का कोई तरीका होगा।

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

+0

यह सी-स्टाइल कोड नहीं है, और इसका एक महत्वपूर्ण हिस्सा मेरे नियंत्रण में नहीं है। जबकि मैं सामान्य ऑपरेशन के तहत इस तीसरे पक्ष के कोड पर भरोसा करता हूं, जब ओओएम अपवाद फेंक दिया जाता है तो मुझे नहीं लगता कि मैं कोई धारणा कर सकता हूं, भले ही अपवाद हैंडलिंग सक्षम हो। "_ आपको DLL._ से आवंटित किसी भी स्मृति को मैन्युअल रूप से रिलीज़ करने का कोई तरीका होगा।" यह वही है जो मेरा प्रश्न है। :-) –

+0

क्षमा करें, लेकिन मुझे लगता है कि वास्तव में ऐसा करने का कोई तरीका नहीं है जो आप चाहते हैं। अपने स्वयं के प्लगइन प्रकार सिस्टम में "डीएलएल से मैन्युअल रिलीज" प्राप्त करने के लिए, मुझे एक कस्टम आवंटन दिनचर्या का उपयोग करने के लिए आवंटित करने के लिए सभी क्लाइंट कोड की आवश्यकता होती है जो डीएलएल को मेरी मूल आपूर्ति प्रदान करता है। यह एसोसिएशन कोर को जितना चाहें उतना डीएलएल छोड़ने की अनुमति देता है। लेकिन अगर आप इसे स्वयं लागू नहीं कर सकते हैं, तो मुझे नहीं लगता कि यह किया जा सकता है। – Stephen