c# - why am I getting a System.OutOfMemoryException -


मैं Linq को SQL का उपयोग कर रहा हूँ यहां कोड है:

  शब्दकोष & lt; स्ट्रिंग, इंट & gt; allResults; (Var dc = नया MyDataContext ()) का उपयोग कर {dc.CommandTimeout = 0; AllResults = dc.MyTable.ToDictionary (x = & gt; x.Text, x = & gt; x.Id); }  

यह एक 64 बिट मशीन पर चल रहा है और संकलन AnyCPU है यह एक System.OutOfMemoryException फेंकता है।

यह एक SQL सर्वर डेटाबेस तक पहुँचता है एक एसक्यूएल सर्वर int फ़ील्ड के लिए आईडी फ़ील्ड मैप्स, और टेक्स्ट फ़ील्ड मैप्स को पाठ (एनवर्चार (मैक्स)) फ़ील्ड में। तालिका नाम से चुनें COUNT (*) का चयन करें परिणाम 1,173,623 रिकॉर्ड और चल रहे तालिकानाम से चुनें (लेनन (पाठ)) से तालिका नाम परिणामों में 48,915,031 चूंकि पूर्णांक एक 32 बिट पूर्णांक है, आईआईडी को केवल 4.6 9 एमबी का स्थान और 1 जीबी से कम स्ट्रिंग लेना चाहिए। इसलिए हम 2 जीबी / ऑब्जेक्ट सीमा के खिलाफ भी टक्कर नहीं दे रहे हैं।

तब मैं इस तरह से कोड बदलूंगा:

  शब्दकोष & lt; स्ट्रिंग, इंट & gt; allResults; (Var dc = new MyDataContext ()) का उपयोग करते हुए {शब्दकोश & lt; स्ट्रिंग, इंट & gt; तीन सौ; Dc.CommandTimeout = 0; Var tot = dc.MyTable.Count (); AllResults = नया शब्दकोश & lt; स्ट्रिंग, int & gt; (tot); Int छोड़ = 0; Int takeThis = 300000; जबकि (छोड़कर & lt; tot) {threeHundred = dc.MyTable.Skip (skip)। ले लो (takeThis) .ऑयोगिनेशन (x = & gt; x.Text, x = & gt; x.Id); Skip = skip + takeThis; AllResults = allResults.Concat (तीन हंडो) .ऑनोकेशन (एक्स = & gt; x.Key, x = & gt; x.Value); तीन सौ = नल; GC.Collect (); }}  

मुझे पता है कि यहां कचरा संलयन मदद नहीं करता है और यह कि मेमोरी अपवाद से बाहर निकलने पर पहली पंक्ति पर पहली बार लूप को छोड़ दिया जाता है, एक बार = 900,000 छोड़ देता है।

गलत क्या है और मैं इसे कैसे ठीक कर सकता हूं?

स्मृति में ले लो (जैसा कि एन्कोडिंग के मुद्दे हो सकता है जो आसानी से डेटा के आकार को दोहरा सकता है), मैं कुछ संकेत देने की कोशिश करूंगा।

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

कृपया मुझे इस लेख को पढ़िए जिसे मैंने आंतरिक इंटरनेशनल में गहराई से चलाया है - मुझे यकीन है कि यह होगा उन लक्षणों पर कुछ प्रकाश डालें

इसके अतिरिक्त, जब इस बड़ी मात्रा में डेटा को आबाद करने की कोशिश कर रहा हो, तो मैं पूरी तरह से इस प्रक्रिया को नियंत्रित करने का सुझाव देता हूं। मेरा सुझाव:

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

किसी भी तरह से, आपको जांचना चाहिए कि क्या आप 32 बिट या 64 बिट पर चल रहे हैं। 4.5 को 32 बिट पसंद करते हैं। (इसे टास्क मैनेजर या प्रोजेक्ट प्रॉपर्टी पर देखें)

आशा है कि यह मदद करता है, ऑफिस।


Comments

Popular posts from this blog

import - Python ImportError: No module named wmi -

Editing Python Class in Shell and SQLAlchemy -

c# - MySQL Parameterized Select Query joining tables issue -