मेरे एप्लिकेशन को अपना काम करने के लिए बहुत सारी मेमोरी और बड़ी डेटा संरचना की आवश्यकता है। अक्सर एप्लिकेशन को 1 जीबी से अधिक मेमोरी की आवश्यकता होती है, और कुछ मामलों में मेरे ग्राहकों को वास्तव में एप्लिकेशन के 64-बिट संस्करण का उपयोग करने की आवश्यकता होती है क्योंकि उनके पास स्मृति के कई गीगाबाइट हैं।विंडोज़ को डीएलएल को स्थानों पर लोड करने के लिए मजबूर करना ताकि स्मृति को न्यूनतम रूप से विभाजित किया जा सके
अतीत में, मैं आसानी से उपयोगकर्ता को समझा सकता हूं कि यदि स्मृति 1.6 से 1.7 जीबी मेमोरी उपयोग तक पहुंच गई, तो यह 'स्मृति से बाहर' या वास्तव में 'स्मृति से बाहर' स्थिति के करीब थी, और उन्हें चाहिए उनकी याददाश्त को कम करने या 64-बिट संस्करण में जाने के लिए।
पिछले साल मैंने देखा कि अक्सर एप्लिकेशन केवल स्मृति से बाहर होने से पहले लगभग 1 जीबी का उपयोग करता है। कुछ जांच के बाद ऐसा लगता था कि इस समस्या का कारण स्मृति विखंडन है। मैंने अपने आवेदन के मेमोरी उपयोग को देखने के लिए वीएमएमएपी (एक SysInternals उपयोगिता) का उपयोग किया और इस तरह कुछ देखा:
नारंगी क्षेत्रों को मेरे आवेदन द्वारा आवंटित स्मृति है। बैंगनी क्षेत्र निष्पादन योग्य कोड हैं।
जैसा कि आप छवि के निचले हिस्सों में देख सकते हैं, बैंगनी क्षेत्रों (जो डीएलएल हैं) कई अलग-अलग पतों पर लोड होते हैं, जिससे मेरी स्मृति को खंडित किया जाता है। यह वास्तव में एक समस्या नहीं है यदि मेरे ग्राहक के पास बहुत अधिक डेटा नहीं है, लेकिन यदि मेरे ग्राहक के पास डेटा सेट हैं जो 1 जीबी से अधिक लेते हैं, और एप्लिकेशन के एक हिस्से को स्मृति के एक बड़े ब्लॉक (जैसे 50 एमबी) की आवश्यकता होती है, इसके परिणामस्वरूप स्मृति आवंटन विफलता हो सकती है, जिससे मेरा एप्लिकेशन क्रैश हो जाता है।
मेरे अधिकांश डेटा संरचनाएं एसटीएल आधारित हैं और अक्सर संगत स्मृति के बड़े हिस्से की आवश्यकता नहीं होती है, लेकिन कुछ मामलों में (जैसे बहुत बड़े तार), वास्तव में स्मृति की एक संगत ब्लॉक होने की आवश्यकता होती है। दुर्भाग्यवश, कोड को हमेशा बदलना हमेशा संभव नहीं है ताकि इसे स्मृति के इस तरह के एक जटिल ब्लॉक की आवश्यकता न हो।
प्रश्न हैं:
- मैं स्थान जहां DLL की स्मृति में लोड किए गए हैं, स्पष्ट रूप से सभी DLL के ग्राहक के कंप्यूटर पर पर rebase का उपयोग किए बिना कैसे प्रभावित कर सकते हैं, या सभी DLL का स्पष्ट रूप से लोड किए बिना।
- क्या आपके स्वयं के एप्लिकेशन मेनिफेस्ट फ़ाइल में डीएलएल के लोड पते निर्दिष्ट करने का कोई तरीका है?
- या क्या डीएलएल के आसपास स्कैटर नहीं करने के लिए विंडोज़ (मैनिफेस्ट फ़ाइल के माध्यम से) को बताने का कोई तरीका है (मुझे लगता है कि इस स्कैटरिंग को एएसएलआर कहा जाता है)।
बेशक सबसे अच्छा समाधान वह है जिसे मैं अपने एप्लिकेशन की मेनिफेस्ट फ़ाइल में से प्रभावित कर सकता हूं, क्योंकि मैं विंडोज़ द्वारा डीएलएल की स्वचालित/गतिशील लोडिंग पर भरोसा करता हूं।
मेरा आवेदन एक मिश्रित मोड (प्रबंधित + अप्रबंधित) एप्लिकेशन है, हालांकि एप्लिकेशन का मुख्य हिस्सा अप्रबंधित है।
कोई भी सुझाव?
क्या यह ऐसा कुछ है जो आपकी मदद कर सकता है? http://msdn.microsoft.com/en-us/library/f7f5138s.aspx – detunized
mmm, क्या आपको वास्तव में एक ही समय में उस स्मृति की आवश्यकता है? प्रोसेस मॉनिटर वर्चुअल मेमोरी में अपने लॉग स्टोर करता है और आवश्यकता होने पर केवल प्रक्रिया की मेमोरी एड्रेस स्पेस में डेटा लाता है, कोड के लिए http://blogs.msdn.com/b/oldnewthing/archive/2004/08/10/211890.aspx जांचें उदाहरण –
मुझे यकीन नहीं है कि उत्तर छोड़ने वाले सभी लोग एएसएलआर की विधियों को समझते हैं: http://en.wikipedia.org/wiki/ASLR –