windows - करन - विडियो डाउनलोड करे




Windows को DLL को स्थानों पर लोड करने के लिए मजबूर कर रहा है ताकि स्मृति कम से कम खंडित हो (2)

आप ऐसा प्रकट नहीं कर सकते हैं, यह लिंकर / आधार विकल्प द्वारा किया जाना चाहिए। आईडीई में लिंकर + उन्नत + आधार पता सबसे लचीला तरीका / आधार का प्रयोग करना है: @ फाइलनाम, कुंजी सिंटैक्स ताकि लिंकर टेक्स्ट फ़ाइल से आधार पता पढ़ सके।

टेक्स्ट फाइल भरने का सबसे अच्छा तरीका डीबग + विंडोज + मॉड्यूल विंडो से है। डिबगर में लोड किए गए आपके प्रोग्राम का रिलीज़ बिल्ड प्राप्त करें और पूरे शेबांग को लोड करें डीबग + सभी ब्रेक, विंडो को ऊपर लाएं और इसे टेक्स्ट फ़ाइल में कॉपी-पेस्ट करें। पता कॉलम से लोड पते की गणना करने के लिए, आवश्यक प्रारूप से मेल करने के लिए इसे संपादित करें। DLL के बीच पर्याप्त स्थान छोड़ दें ताकि आप को पाठ फ़ाइल को लगातार बदलना पड़े न हो।

अपने काम को पूरा करने के लिए मेरे आवेदन में बहुत मेमोरी और बड़े डेटा संरचना की आवश्यकता है। अक्सर अनुप्रयोग को 1 जीबी मेमोरी से ज्यादा की जरूरत होती है, और कुछ मामलों में मेरे ग्राहकों को वास्तव में 64-बिट संस्करण का उपयोग करने की आवश्यकता होती है क्योंकि उनके पास स्मृति के कई गीगाबाइट हैं

अतीत में, मैं आसानी से उपयोगकर्ता को समझा सकता हूं कि यदि स्मृति 1.6 से 1.7 जीबी मेमोरी का उपयोग हो, तो यह 'मेमोरी से बाहर' या वास्तव में 'स्मृति से बाहर' स्थिति के करीब था, और उन्हें उनकी स्मृति कम करने की जरूरत थी या 64-बिट संस्करण में स्थानांतरित करें।

पिछले साल मैंने देखा कि यह आवेदन केवल 1 जीबी का उपयोग करता है, इससे पहले कि यह पहले से ही स्मृति से बाहर हो गया। कुछ जांच के बाद ऐसा लग रहा था कि इस समस्या का कारण स्मृति विखंडन है मैंने अपने आवेदन के मेमोरी उपयोग को देखने के लिए VMMAP (एक SysInternals उपयोगिता) का इस्तेमाल किया और ऐसा कुछ देखा:

नारंगी क्षेत्रों मेरे आवेदन द्वारा आवंटित मेमोरी हैं I बैंगनी क्षेत्रों निष्पादन योग्य कोड हैं I

जैसा कि आप छवि के निचले भाग में देख सकते हैं, बैंगनी क्षेत्रों (जो कि डीएलएल हैं) कई अलग-अलग पतों पर लोड किए जाते हैं, जिससे मेरी स्मृति को विखंडित किया जा सकता है। यह वास्तव में एक समस्या नहीं है अगर मेरे ग्राहक में बहुत अधिक डेटा नहीं है, लेकिन अगर मेरे ग्राहक डेटा सेट करते हैं जो 1 जीबी से अधिक लेते हैं, और आवेदन के एक भाग को स्मृति का एक बड़ा ब्लॉक (जैसे 50 एमबी) की आवश्यकता होती है, यह मेमोरी आवंटन विफलता का कारण बन सकता है, जिससे मेरा एप्लिकेशन क्रैश हो जाता है।

मेरे अधिकांश डेटा संरचना एसटीएल-आधारित होते हैं और अक्सर संक्रमित स्मृति के बड़े हिस्से की आवश्यकता नहीं होती है, लेकिन कुछ मामलों में (जैसे बहुत बड़ी स्ट्रिंग्स), वास्तव में स्मृति के निकटवर्ती ब्लॉक की आवश्यकता होती है। दुर्भाग्यवश, कोड को बदलने के लिए हमेशा संभव नहीं होता है जिससे कि उसे स्मृति के ऐसे निकटतम ब्लॉक की आवश्यकता न हो।

प्रश्न ये हैं:

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

बेशक सबसे अच्छा समाधान यह है कि मैं अपने आवेदन की मैनिफ़ेस्ट फ़ाइल के भीतर से प्रभावित कर सकता हूं, क्योंकि मैं विंडोज़ के डीएलएल के स्वत: / गतिशील लोडिंग पर भरोसा करता हूं।

मेरा आवेदन एक मिश्रित मोड है (प्रबंधित + अप्रबंधित) अनुप्रयोग, हालांकि आवेदन का प्रमुख भाग अप्रबंधित है।

कोई भी सुझाव?


सबसे पहले, आपके वर्चुअल पता स्थान विखंडन को आवश्यक रूप से आउट-ऑफ-मेमोरी हालत का कारण नहीं होना चाहिए। यह मामला होगा यदि आपके आवेदन को उचित आकार के निकटतम स्मृति ब्लॉक्स आवंटित करना था। अन्यथा विखंडन का असर नाबालिग होना चाहिए।

आप कहते हैं कि आपके अधिकांश डेटा "एसटीएल-आधारित" हैं, लेकिन उदाहरण के लिए यदि आप एक विशाल std::vector आवंटित करते हैं तो आपको एक निकटतम स्मृति ब्लॉक की आवश्यकता होगी।

AFAIK डीएलएल के लोड लोड पर पसंदीदा मैपिंग पता निर्दिष्ट करने का कोई तरीका नहीं है। इसलिए कि केवल दो विकल्प हैं: या तो इसे रिसाइज़ करें (DLL फ़ाइल), या स्वयं को लोड करने के लिए DLL को कार्यान्वित करें (जो निश्चित रूप से तुच्छ नहीं है)।

आम तौर पर आपको मानक विंडोज एपीआई डीएलएल को रिबेस करने की ज़रूरत नहीं है, वे आपके पते की जगह पर बहुत कसकर लोड होते हैं। फ्रेग्मेंटेशन कुछ तृतीय-पक्ष DLLs से आ सकता है (जैसे विंडो हुक, एंटीवायरस इंजेक्शन और आदि)