2010-01-19 15 views
7

मेरे पास .NET/मूल C++ एप्लिकेशन है। वर्तमान में, सी ++ कोड डिफ़ॉल्ट ढेर पर स्मृति आवंटित करता है जो एप्लिकेशन के जीवन के लिए जारी रहता है। असल में, कार्यों/आदेशों को सी ++ में निष्पादित किया जाता है जिसके परिणामस्वरूप वर्तमान निरंतर स्मृति का आवंटन/संशोधन होता है। मैं इन कार्यों में से किसी एक को रद्द करने के लिए एक दृष्टिकोण की जांच कर रहा हूं/मध्य-निष्पादन आदेश। हमारे पास इनमें से सैकड़ों कमांड हैं, और कई बहुत ही जटिल (विरासत) कोड हैं।क्या Win32 "हिल" आवंटित स्मृति को स्थानांतरित कर सकता है?

क्रूर-बल दृष्टिकोण जिसे मैं टालने की कोशिश कर रहा हूं, रद्द करने की जांच करने के लिए प्रत्येक आदेश/फ़ंक्शन को संशोधित कर रहा है और सभी उचित सफाई (मुक्त ढेर मेमोरी) कर रहा है। मैं एक बहु थ्रेडेड दृष्टिकोण की जांच कर रहा हूं जिसमें एक अतिरिक्त थ्रेड रद्दीकरण अनुरोध प्राप्त करता है और कमांड निष्पादन थ्रेड को समाप्त करता है। मैं HeapCreate() (Win32) का उपयोग कर सभी "गतिशील ढेर" पर सभी गतिशील स्मृति आवंटित करना चाहता हूं। इस तरह, रद्दीकरण अनुरोध को संभालने वाले थ्रेड द्वारा निजी ढेर को नष्ट किया जा सकता है। हालांकि, अगर आदेश पूरा होने के लिए चलता है, तो मुझे जारी रखने के लिए गतिशील स्मृति की आवश्यकता होती है। इस मामले में, मैं एक निजी प्रतिलिपि की लागत के बिना डिफ़ॉल्ट/प्रक्रिया ढेर में निजी ढेर मेमोरी को "चलाना" के तार्किक समकक्ष करना चाहता हूं। क्या यह किसी भी तरह से संभव है? क्या यह भी समझ में आता है?

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

मैं 8 जीबी रैम के साथ विंडोज 7 64-बिट पर चल रहा हूं (इसे लक्षित प्लेटफ़ॉर्म पर विचार करें)। जिस एप्लिकेशन के साथ मैं काम कर रहा हूं वह लगभग 1 मिलियन एसएलओसी (आधा सी ++, आधा सी #) है। मैं निजी ढेर प्रबंधन, या मेरे समाधान के विकल्प के साथ किसी भी अनुभव/सुझाव की तलाश में हूं।

+0

क्या आप पूछ रहे हैं कि एक ही ढेर में आवंटित स्मृति को वास्तव में डेटा की प्रतिलिपि किए बिना किसी अन्य ढेर में "पुनः निर्दिष्ट" किया जा सकता है? –

+0

मुझे 92% यकीन है कि उत्तर नहीं है। लेकिन इसे उत्तर के रूप में पोस्ट करने के लिए पर्याप्त नहीं है। –

+6

हीप मेमोरी आवंटन केवल एकमात्र समस्या नहीं है जिसे आप जबरन थ्रेड को समाप्त कर देंगे। धागे को समाप्त करने का एकमात्र सुरक्षित तरीका अंदर से है। इस तरह, आप जानते हैं कि थ्रेड कुछ लॉक ऑपरेशन के बीच में नहीं है। अंतःक्रियाशीलता को आपके कार्यों की एक आंतरिक विशेषता होना चाहिए; यह ऐसा कुछ नहीं है जिसे आप बाहर से बोल्ट कर सकते हैं। –

उत्तर

1

ढेर स्मृति के बड़े हिस्से का एक प्रकार है। यह एक उपयोगकर्ता के स्तर स्मृति प्रबंधक है। एक ढेर निचले स्तर सिस्टम स्मृति कॉल (जैसे, लिनक्स और VirtualAlloc में sbrk द्वारा बनाई गई है विंडो में ws)। एक ढेर में, आप malloc/new/free/delete द्वारा स्मृति का एक छोटा हिस्सा अनुरोध या वापस कर सकते हैं। डिफ़ॉल्ट रूप से, एक प्रक्रिया में एक ही ढेर होता है (ढेर के विपरीत, सभी थ्रेड एक ढेर साझा करते हैं)। लेकिन, आप कई ढेर हो सकते हैं।

  • यह दो ढेर w/ओ नकल गठबंधन करने के लिए संभव है? एक ढेर अनिवार्य रूप से एक डेटा संरचना है जो उपयोग और मुक्त स्मृति खंडों की एक सूची बनाए रखती है। तो, एक ढेर में मेटा डेटा नामक एक प्रकार का बहीखाता डेटा होना चाहिए। बेशक, यह मेटा डेटा प्रति ढेर है। AFAIK, कोई ढेर प्रबंधक दो ढेर के मर्ज ऑपरेशन का समर्थन करता है। मैंने लिनक्स ग्लिब (Doug Lea's implementation) में मॉलोक कार्यान्वयन के पूरे स्रोत कोड की समीक्षा की थी, लेकिन ऐसा कोई ऑपरेशन नहीं था। विंडोज हीप * कार्यों को भी इसी तरह कार्यान्वित किया जाता है। तो, वर्तमान में दो अलग-अलग ढेर को स्थानांतरित या विलय करना असंभव है।

  • क्या यह कई ढेर हो सकता है? मुझे नहीं लगता कि कई ढेर होने में बड़ी समस्या होनी चाहिए। जैसा कि मैंने पहले कहा था, एक ढेर सिर्फ एक डेटा संरचना है जो स्मृति/भाग को मुक्त/मुक्त रखती है। तो, कुछ ओवरहेड होना चाहिए। लेकिन, यह गंभीर नहीं है। जब आप malloc implementation में से किसी एक को देखते हैं, तो malloc_state है, जो प्रत्येक ढेर के लिए मूल डेटा संरचना है। उदाहरण के लिए, आप create_mspace (विंडोज़ में, यह HeapCreate) द्वारा एक और ढेर बना सकते हैं, फिर आपको एक नया मॉलोक स्टेट मिलेगा। यह इतना बड़ा नहीं है। तो, अगर यह ट्रेड-ऑफ (कुछ ढेर ओवरहेड बनाम कार्यान्वयन आसानता) ठीक है, तो आप आगे बढ़ सकते हैं।

यदि मैं आप थे, तो मैं आपके द्वारा वर्णित तरीके का प्रयास करूंगा। यह मुझे समझ में आता है। बहुत सारे ढेर ऑब्जेक्ट्स होने से बड़ा ओवरहेड नहीं बनता है।

इसके अलावा, यह ध्यान दिया जाना चाहिए कि तकनीकी रूप से चल रहे स्मृति क्षेत्र असंभव हैं। पॉइंटर्स जो स्थानांतरित स्मृति क्षेत्र की ओर इशारा करते हैं, परिणामस्वरूप लटकने वाले पॉइंटर्स होंगे।

पेज। आपकी समस्या एक लेनदेन की तरह लगती है, खासकर सॉफ्टवेयर ट्रांजैक्शनल मेमोरी। स्मृति लंबित एसटीएम बफर का एक सामान्य कार्यान्वयन लिखता है, और फिर असली सिस्टम मेमोरी में आता है, लेनदेन के पास कोई संघर्ष नहीं था।

+0

@STingRaySC: आभासी पता और भौतिक पते के बीच मैपिंग इस समस्या से कोई लेना देना नहीं है। हम बस इस तरह के मैपिंग नहीं देख सकते हैं। हम केवल आभासी पता स्थान में चाल/विलय पर विचार कर रहे हैं।प्रोग्रामर केवल वर्चुअल एड्रेस देख सकते हैं (कुछ मनोनीत या वास्तविक-मोड स्थितियों को छोड़कर)। हां, भौतिक पते पर मैपिंग हमेशा बदला जा सकता है, लेकिन यह पूरी तरह से छुपा हुआ है। हालांकि, बी/डब्ल्यू ढेर चलाना/विलय करना केवल वर्चुअल एड्रेस रिक्त स्थान के भीतर किया जाता है, इसलिए, यह आम तौर पर असंभव है जब तक कि हम संदर्भित पॉइंटर्स को ट्रैक करने के लिए बहुत महंगा तंत्र लागू नहीं करते हैं। – minjang

1

नहीं। मेमोरी ढेर के बीच स्थानांतरित नहीं किया जा सकता है।

4

आप अलग प्रक्रियाओं अलग धागे के बजाय के साथ बंद बेहतर हो सकता है:

  • उपयोग स्मृति मैप की गई फ़ाइलों (यानी नहीं एक फ़ाइल बिल्कुल - बस पार संसाधित साझा स्मृति)
  • एक प्रक्रिया की मौत हो गई है ' 'एक धागा की हत्या से
  • मुझे लगता है कि आप साझा स्मृति हो सकता है' क्लीनर एक कदम के बिना हत्या जीवित रहने '- आप मैप/unmap ले जाने के बजाय

हालांकि आपको अपने आप में कुछ मेमोरी प्रबंधन करने की आवश्यकता हो सकती है।

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

बस एक विचार!

2

MSDN के Heap Functions पृष्ठ से: "मेमोरी HeapAlloc द्वारा आवंटित चल नहीं है पता HeapAlloc द्वारा दिया मान्य है जब तक स्मृति ब्लॉक मुक्त कर दिया या पुनः आवंटन की है, स्मृति ब्लॉक बंद किया जा की जरूरत नहीं है।।"

क्या आप अपने स्वयं के malloc() कार्यान्वयन के खिलाफ विरासत ऐप्स को फिर से लिंक कर सकते हैं? यदि ऐसा है, तो आप शेष कोड को संशोधित किए बिना प्रबंधित करने में सक्षम होना चाहिए।आपकी कस्टम मॉलोक लाइब्रेरी थ्रेड द्वारा आवंटित ब्लॉक ट्रैक कर सकती है, और "फ्रीएल्बटी थ्रेड() फ़ंक्शन जिसे आप विरासत फ़ंक्शन के थ्रेड को मारने के बाद कॉल करते हैं। आप लाइब्रेरी के अंदर निजी ढेर का उपयोग कर सकते हैं।

निजी ढेर का एक विकल्प हो सकता है स्मृति-मैप की गई फ़ाइलों से अपना स्वयं का आवंटन। "Creating Named Shared Memory" देखें। आप लीगेसी थ्रेड के लिए आवंटन लाइब्रेरी को प्रारंभ करते समय साझा स्मृति बनाते हैं। सफलता पर, इसे मुख्य थ्रेड में मैप करें ताकि आपका सी # इसे एक्सेस कर सके; समाप्ति पर, इसे बंद करें और यह व्यवस्था करने के लिए जारी किया गया है।

+0

GetCurrentThreadId() विंडोज एपीआई – tony

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