8

मेरा एप्लिकेशन बाइनरी क्रमबद्धरण और बड़ी वस्तुओं के संपीड़न का एक अच्छा सौदा करता है। धारावाहिक डेटासेट को असम्पीडित लगभग 14 एमबी है। संकुचित यह लगभग 1.5 एमबी है। मुझे लगता है कि जब भी मैं अपने डेटासेट पर धारावाहिक विधि को कॉल करता हूं तो मेरा बड़ा ऑब्जेक्ट हीप प्रदर्शन काउंटर 1 एमबी से लगभग 9 0 एमबी तक बढ़ जाता है। मुझे यह भी पता है कि अपेक्षाकृत भारी भारित प्रणाली के तहत, आम तौर पर चलने (कुछ दिनों) के दौरान, जब यह क्रमिकरण प्रक्रिया कुछ समय होती है, तो एप्लिकेशन को स्मृति उत्तेजनाओं से बाहर फेंकने के लिए जाना जाता है जब इस धारावाहिक विधि को तब भी कहा जाता है लगता है कि बहुत मेमोरी है। मुझे लगता है कि विखंडन मुद्दा है (हालांकि मैं नहीं कह सकता कि मैं 100% निश्चित हूं, मैं बहुत करीब हूं)क्या मुझे जीसी को कॉल करना चाहिए। विखंडन को रोकने के लिए बड़े ऑब्जेक्ट ढेर का उपयोग करने के तुरंत बाद चयन करें

सबसे सरल शॉर्ट टर्म फिक्स (मुझे लगता है कि मैं एक अल्पकालिक दोनों की तलाश में हूं और एक दीर्घकालिक उत्तर) मैं सोच सकता हूं कि जीसी को कॉल करना है। सीरियलाइजेशन प्रक्रिया पूरी करने के बाद ठीक से चयन करें। यह मेरी राय में, कचरे को एलओएच से वस्तु एकत्र करेगा और इससे पहले कि अन्य वस्तुओं को इसमें जोड़ा जा सके, ऐसा करने की संभावना है। यह अन्य वस्तुओं को ढेर में शेष वस्तुओं के खिलाफ कसकर कसकर फिट करने की अनुमति देगा बिना विखंडन के।

इस हास्यास्पद 90 एमबी आवंटन के अलावा मुझे नहीं लगता कि मेरे पास LOH के खोने का उपयोग करने वाला कुछ और है। यह 9 0 एमबी आवंटन भी अपेक्षाकृत दुर्लभ है (हर 4 घंटे के आसपास)। निश्चित रूप से हमारे पास अभी भी 1.5 एमबी सरणी होगी और शायद कुछ अन्य छोटे धारावाहिक वस्तुएं होंगी।

कोई विचार? अच्छा प्रतिक्रियाओं

के परिणामस्वरूप

अद्यतन यहाँ मेरी कोड है जो काम करता है। मैंने वास्तव में WHILE धारावाहिक को संपीड़ित करने के लिए इसे बदलने की कोशिश की है ताकि धारावाहिक एक ही समय में एक धारा में क्रमबद्ध हो और मुझे बेहतर परिणाम न मिले। मैंने मेमोरी स्ट्रीम को 100 एमबी तक प्रीलोकेट करने का प्रयास किया है और एक ही स्ट्रीम को लगातार दो बार उपयोग करने की कोशिश की है, LOH वैसे भी 180 एमबी तक चला जाता है। मैं इसे मॉनीटर करने के लिए प्रोसेस एक्सप्लोरर का उपयोग कर रहा हूं। यह पागल है। मुझे लगता है कि मैं अगले अप्रबंधित मेमरीस्ट्रीम विचार का प्रयास करने जा रहा हूं।

मैं आपको लोगों को प्रोत्साहित करने के लिए प्रोत्साहित करता हूं यदि आप नहीं चाहते हैं। यह सटीक कोड नहीं होना चाहिए। बस एक बड़े डाटासेट को क्रमानुसार और आप आश्चर्य की बात परिणाम मिलेंगे अगर मैं UnmanagedMemoryStream के साथ द्विआधारी क्रमांकन कोशिश कर

के बाद भी

 byte[] bytes; 
     System.Runtime.Serialization.Formatters.Binary.BinaryFormatter serializer = 
     new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();    
     System.IO.MemoryStream memStream = new System.IO.MemoryStream(); 
     serializer.Serialize(memStream, obj); 
     bytes = CompressionHelper.CompressBytes(memStream.ToArray()); 
     memStream.Dispose(); 
     return bytes; 

अद्यतन (मेरा तालिकाओं के बहुत सारे, 15 arround और तार के बहुत सारे और स्तंभ होते हैं) एक unmanagedMemoryStream के लिए serialize LOH एक ही आकार तक कूदता है। ऐसा लगता है कि कोई फर्क नहीं पड़ता कि मैं क्या करता हूं, जिसे इस बड़ी वस्तु को क्रमबद्ध करने के लिए बाइनरीफॉर्मेटर कहा जाता है, वह LOH का उपयोग करेगा। प्री-आवंटन के लिए, यह बहुत मदद नहीं करता है। मान लें कि मैं पूर्व-आवंटित करता हूं कि मैं 100 एमबी प्रीलाकेट करता हूं, फिर मैं धारावाहिक करता हूं, यह 170 एमबी का उपयोग करेगा। इसके लिए कोड यहाँ है। उपरोक्त कोड

BinaryFormatter serializer = new BinaryFormatter(); 
MemoryStream memoryStream = new MemoryStream(1024*1024*100); 
GC.Collect(); 
serializer.Serialize(memoryStream, assetDS); 

GC.Collect() बीच में वहाँ LOH प्रदर्शन काउंटर अद्यतन करने के लिए बस है की तुलना में और भी आसान। आप देखेंगे कि यह सही 100 एमबी आवंटित करेगा। लेकिन फिर जब आप धारावाहिक कहते हैं, तो आप देखेंगे कि ऐसा लगता है कि 100 के शीर्ष पर जो आप पहले ही आवंटित कर चुके हैं।

+4

क्या कोई ऐसा चीज है जो आप LOH को बफर के रूप में उपयोग करने के बजाय सीधे 'स्ट्रीम' पर क्रमबद्ध करने के लिए कर सकते हैं? –

उत्तर

3

दुर्भाग्यवश, मैं इसे ठीक करने का एकमात्र तरीका था, जो डेटा को तोड़ने के लिए था ताकि LOH पर बड़े हिस्से आवंटित न किए जाएं। यहां सभी प्रस्तावित उत्तर अच्छे थे और काम करने की उम्मीद थी लेकिन उन्होंने नहीं किया।ऐसा लगता है कि .NET में बाइनरी क्रमबद्धता (.NET 2.0 SP2 का उपयोग करके) अपने स्वयं के छोटे जादू को हुड के नीचे करता है जो उपयोगकर्ताओं को स्मृति आवंटन पर नियंत्रण रखने से रोकता है।

प्रश्न के उत्तर में "यह काम करने की संभावना नहीं है"। जब .NET क्रमबद्धता का उपयोग करने की बात आती है, तो आपकी सबसे अच्छी शर्त छोटी वस्तुओं में बड़ी वस्तुओं को क्रमबद्ध करना है। अन्य सभी परिदृश्यों के लिए, ऊपर वर्णित उत्तरों महान हैं।

2

9 0 एमबी रैम ज्यादा नहीं है।

जीसी कॉल करने से बचें। जब तक आपको कोई समस्या न हो तब तक चयन करें। यदि आपको कोई समस्या है, और कोई बेहतर समाधान नहीं है, तो जीसी को कॉल करने का प्रयास करें। देखें और आपकी समस्या हल हो गई है या नहीं।

4

संग्रह कक्षाओं और स्ट्रीम जैसे मेमरीस्ट्रीम काम जैसे .NET में सावधान रहें। उनके पास एक अंतर्निहित बफर है, एक साधारण सरणी है। जब भी संग्रह या स्ट्रीम बफर सरणी के आवंटित आकार से आगे बढ़ता है, तो सरणी को फिर से आवंटित किया जाता है, अब पिछले आकार में दोगुना हो जाता है।

यह LOH में सरणी की कई प्रतियां पैदा कर सकता है। आपका 14 एमबी डेटासेट 128 केबी पर LOH का उपयोग करना शुरू कर देगा, फिर एक और 256 केबी लें, फिर एक और 512 केबी, इत्यादि। आखिरी वाला, वास्तव में इस्तेमाल किया जाने वाला एक, लगभग 16 एमबी होगा। LOH में इनमें से योग है, लगभग 30 एमबी, जिनमें से केवल वास्तविक उपयोग में है।

जीन 2 संग्रह के बिना यह तीन बार करें और आपका LOH 90MB हो गया है।

बफर को अपेक्षित आकार में पूर्व-आवंटित करके इसे से बचें। मेमोरीस्ट्रीम में एक कन्स्ट्रक्टर है जो प्रारंभिक क्षमता लेता है। तो सभी संग्रह वर्गों करो। सभी संदर्भों को रद्द करने के बाद जीसी.कोलेक्ट() को कॉल करना, LOH को अनजाने में मदद कर सकता है और उन इंटरमीडिएट बफर को शुद्ध कर सकता है, जो कि जल्द ही gen1 और gen2 ढेर को छिपाने की लागत पर है।

0

यदि आपको वास्तव में किसी सेवा या किसी ऐसे समय के लिए LOH का उपयोग करने की आवश्यकता है जो लंबे समय तक चलने की आवश्यकता है, तो आपको बफर पूल का उपयोग करने की आवश्यकता है जिसे कभी भी हटाया नहीं जाता है और आप आदर्श रूप से स्टार्ट-अप पर आवंटित कर सकते हैं। इसका मतलब है कि आपको इसके लिए अपना 'मेमोरी मैनेजमेंट' करना होगा।

इस स्मृति के साथ आप जो कर रहे हैं उसके आधार पर, आपको कुछ हिस्सों को कॉल करने से बचने के लिए चयनित हिस्सों के लिए मूल कोड पर पी/इनवॉर्ज़ करना पड़ सकता है जो आपको नए आवंटित स्थान पर डेटा डालने के लिए मजबूर करता है LOH में

यह मुद्दों के बारे में एक अच्छा प्रारंभिक बिंदु लेख है: http://blogs.msdn.com/maoni/archive/2004/12/19/327149.aspx

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

जीसी.कोलेक्ट.आईआईआरसी, जीसी.कोलेक्ट (एन) के बारे में प्रलेखन पर भी पढ़ें, केवल यह कहता है कि यह पीढ़ी एन से आगे नहीं एकत्र करता है - यह वास्तव में कभी पीढ़ी के लिए नहीं मिलता है।

0

LOH आकार कूदने के बारे में चिंता न करें। LOH आवंटित/हटाने के बारे में चिंता करें। LOH के बारे में बहुत गूंगा - नियमित रूप से ढेर से दूर LOH ऑब्जेक्ट्स आवंटित करने के बजाय, यह अगले उपलब्ध वीएम पृष्ठ पर आवंटित करता है। मेरे पास एक 3 डी ऐप है जो LOH और नियमित ऑब्जेक्ट्स दोनों को आवंटित/डिलीकेट करता है - नतीजा (जैसा कि डीबगडिआग डंप रिपोर्ट में देखा गया है) यह है कि छोटे ढेर और बड़े ढेर के पृष्ठ पूरे रैम को बदलते हैं, जब तक कि कोई बड़ा हिस्सा न हो अनुप्रयोगों के 2 जीबी वीएम अंतरिक्ष छोड़ दिया। समाधान जब संभव हो तो आवंटित करना है, और फिर इसे जारी न करें - अगली बार इसे फिर से उपयोग करें।

अपनी प्रक्रिया का विश्लेषण करने के लिए डीबगडिएग का उपयोग करें। देखें कि कैसे वीएम पते धीरे-धीरे 2 जीबी पता चिह्न की ओर बढ़ते हैं। फिर एक बदलाव करें जो इसे होने से रोकता है।

0

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

आपको यह Channel 9 video सहायक मिल सकता है जो कचरा कलेक्टर पर दबाव को कम करने के तरीकों पर चर्चा करता है।