2009-05-26 14 views
7

मुझे तारों की एक बड़ी सूची बनाने और इसे स्मृति में रखने की आवश्यकता है, हालांकि इसे एक आउटऑफमेमरी अपवाद को फेंक दिया गया है। संसाधन मॉनिटर के अनुसार मेरे पास अभी भी 1 जीबी मेमोरी उपलब्ध है। मुझे this KB article समस्या को संबोधित करने के लिए मिला, लेकिन ऐसा लगता है कि इसे फ्रेमवर्क 1.1 एसपी 1 (मैं 3.5 एसपी 1 का उपयोग कर रहा हूं) में तय किया जाना चाहिए था।आउटऑफमेमरी एक्सेप्शन फेंक दिया गया है जबकि स्मृति अभी भी उपलब्ध है

क्या कोई दृश्यों के पीछे क्या होता है इस पर कुछ प्रकाश डाल सकता है? क्या .NET फ्रेमवर्क सीमित करता है कि एक ही प्रक्रिया (32 बिट सिस्टम पर) द्वारा कितनी मेमोरी का उपयोग किया जा सकता है? यदि ऐसा है तो मैं देख सकता हूं कि क्यों, लेकिन यह समझ में नहीं आता है कि एप्लिकेशन केवल 1.6 जीबी का उपयोग कर रहा है और अभी भी ~ 1 जीबी सिस्टम को छोड़ दिया गया है।

मैं एक सूची है (। हाँ, मैं कुछ और ही इस्तेमाल कर सकते हैं, लेकिन मैं अभी सही प्रोटोटाइप रहा हूँ), मैं उत्पन्न: -

संपादित करें जो लोग यहां से पूछा के लिए कुछ और में गहराई से जानकारी है एक Guid.NewGuid()। ToString() करके एक यादृच्छिक स्ट्रिंग, और इसे सूची में फेंक दें। जो मैं करने की कोशिश कर रहा हूं वह कई वस्तुओं के साथ एक सूची उत्पन्न करता है जैसा कि मैं इसमें फिट कर सकता हूं, और एक विशिष्ट को देखने के विभिन्न तरीकों का परीक्षण कर सकता हूं। मेरा पहला अनुमान था कि कुछ विखंडन चल रहा है, लेकिन मैंने नीचे दिए गए कोड को छोड़कर सबकुछ गिरा दिया, और यह अभी भी होता है। मुझे नहीं लगता कि यह छोटा स्निपेट बहुत विखंडन पैदा कर सकता है, लेकिन शायद मैं गलत हूं।

 List<string> blah = new List<string>(); 

     for (int i = 0; i < 50000000; i++) 
     { 
      blah.Add(Guid.NewGuid().ToString()); 
     } 
+0

क्या आप आउटऑफमेमरी अपवाद को मार रहे हैं, जहां आप एक कोड स्निपेट प्रदान कर सकते हैं? –

+0

आप किस डेटा संरचना का उपयोग कर रहे हैं? सूची ? – RichardOD

उत्तर

9

के लिए इन लिंक देखें समस्या शायद यह है कि आप "उपलब्ध" स्मृति की जरूरत नहीं है, लेकिन अधिक संभावना है कि आपने नहीं है स्मृति को इतना खंडित किया गया है कि जब आप किसी आइटम को सूची में जोड़ने का प्रयास करते हैं, और इसे आकार बदलना चाहिए, तो उपलब्ध स्मृति का कोई भी ब्लॉक इसे पकड़ नहीं सकता है।

इससे आउटऑफमेमरी अपवाद भी हो जाएगा।

दूसरी बात यह है कि, जब आप अपवाद प्राप्त करते हैं, तो वास्तव में या मोटे तौर पर, आपके पास कितने तार हैं?

और आप सूची को कैसे पॉप्युलेट कर रहे हैं? क्या आप पहले से ही उन वस्तुओं की संख्या जानते हैं जिन्हें आप जोड़ना चाहते हैं? और यदि हां, तो क्या आप सूची बनाते समय क्षमता निर्दिष्ट करते हैं?

यदि आप नहीं जानते हैं, तो इसे समझना संभव होगा, तो आप उस क्षमता को निर्दिष्ट कर सकते हैं?

+0

सूची के आकार को निर्दिष्ट करते हुए, धन्यवाद! – Joe

0

मैं वास्तव में इस बग की बारीकियों पता नहीं है, लेकिन मैं इस में चलाने की थी, या कुछ बहुत समान, साल पहले। अनिवार्य हमने पाया कि जीडीआई हैंडल की मात्रा पर एक कठिन सीमा थी जिस पर आपका आवेदन बाध्य था। कुछ 9, 999 की तरह। जब आप इस सीमा को दबाते हैं तो एप्लिकेशन स्मृति अपवाद से बाहर हो जाएगा चाहे कितनी मेमोरी मुक्त हो।

तो आप कुछ ऐसा कर सकते हैं, लेकिन चूंकि आपने बताया है कि आप तारों के साथ काम कर रहे हैं, मुझे लगता है कि आप ढेर को तोड़ रहे हैं और इसकी क्षमता को पार कर रहे हैं। यदि आपके तार काफी बड़े हैं, तो वे शायद बड़े ऑब्जेक्ट ढेर पर हैं। मुझे लगता है कि ढांचे के शुरुआती संस्करण में LOH के लिए कार्यान्वयन बहुत खराब था। अगर स्मृति सही ढंग से मेरी सेवा करती है, तो ऑब्जेक्ट्स को ठीक से हटाया नहीं जाता है, जिससे केवल LOH पर स्थान से बाहर निकलना बहुत आसान हो जाता है।

कुछ और जानकारी

http://www.simple-talk.com/dotnet/.net-framework/the-dangers-of-the-large-object-heap/ http://msdn.microsoft.com/en-us/magazine/cc534993.aspx http://blogs.msdn.com/maoni/archive/2006/04/18/large-object-heap.aspx http://social.msdn.microsoft.com/Forums/en-US/clr/thread/08e6bd5f-613e-41ae-9ab1-b05c7ff2710f

9

Win32 मेमोरी पर 2 जीबी प्रति प्रक्रिया सीमा है।खैर, वास्तव में 4 जीबी, लेकिन 2 जीबी कर्नेल-मोड के लिए आरक्षित है, जब तक आपके पास /3GB ओएस स्टार्टअप विकल्प सेट न हो।

+1

वह केवल 1.6 जीबी दिखा रहा है, लेकिन मैं शर्त लगाता हूं कि वह विखंडन के लिए कुछ खो रहा है। –

+1

मार्क रसेलिनोविच के ब्लॉग में विंडोज़ भौतिक मेमोरी की सीमाओं पर गहराई से जानकारी है- http://blogs.technet.com/markrussinovich/archive/2008/07/21/3092070.aspx – RichardOD

+1

इसके अलावा पी एंड पी प्रिस्क्रिप्क्शनल आर्किटेक्चर में स्मृति- http://msdn.microsoft.com/en-us/library/ms998583.aspx#scalenetchapt17_topic9 – RichardOD

2

सूची < टी > का डिफ़ॉल्ट कन्स्ट्रक्टर आंतरिक संग्रहण के रूप में एक खाली सरणी के साथ शुरू होता है। एक सरणी आकार बदलने के लिए एक कॉल (टी आइटम) चेक की आवश्यकता है, और क्षमता क्षमता गुण (EnsureCapacity विधि के माध्यम से) होगा। जब क्षमता संपत्ति के सेट होने पर ...

  1. नया आकार (डबल मूल!) नया एक में पुराने एक से
  2. प्रतियां तत्वों के साथ एक नई सरणी बनाता है।
  3. नए में आंतरिक संदर्भ बदलता है।

तो, n का क्षमता संभालने आकार आप 3n की कुल स्मृति उपयोग है दौरान अर्थ होगा कि।

आपकी सूची में विफल होने पर आपकी कितनी वस्तुएं होती हैं? कन्स्ट्रक्टर का उपयोग करने का प्रयास करें जो क्षमता स्वीकार करता है यदि आपको पता है कि कितने आइटम जोड़े जाएंगे। यह किसी भी आकार से बचाता है जिसे करने की आवश्यकता हो सकती है (और अगर आपको बड़ी मेमोरी ब्लॉक की आवश्यकता होती है तो सीधे अपने आउटऑफमेमरी अपवाद को फेंक सकता है)।

1

विखंडन, LARGEADDRESSAWARE, या gcAllowVeryLargeObjects के बारे में भूल ... इस सटीक स्थिति के साथ मेरी समस्या 'पसंद करते हैं 32-बिट' मेरे कंसोल प्रोजेक्ट के गुण पेज में चेकबॉक्स अनचेक, बिल्ड के तहत द्वारा हल किया गया था। यह डिफ़ॉल्ट रूप से सेट किया गया था ... क्यों?

+0

यह मेरे लिए भी काम करता है –

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