जैसा कि आप शायद समझ गए हैं, मुद्दा यह है कि आप स्मृति के एक बड़े सन्निहित ब्लॉक को आवंटित करने की कोशिश कर रहे हैं, जो स्मृति विखंडन के कारण काम नहीं करता है। यदि मुझे वह करने की आवश्यकता है जो आप कर रहे हैं तो मैं निम्नलिखित कार्य करूंगा:
int sizeA = 10000,
sizeB = 10000;
double sizeInMegabytes = (sizeA * sizeB * 8.0) / 1024.0 / 1024.0; //762 mb
double[][] randomNumbers = new double[sizeA][];
for (int i = 0; i < randomNumbers.Length; i++)
{
randomNumbers[i] = new double[sizeB];
}
फिर, एक विशेष सूचकांक प्राप्त करने के लिए जिसका आप उपयोग करेंगे randomNumbers[i / sizeB][i % sizeB]
।
एक अन्य विकल्प यदि आप हमेशा मूल्यों को एक्सेस करते हैं, तो बीज को निर्दिष्ट करने के लिए अतिभारित कंस्ट्रक्टर का उपयोग किया जा सकता है । इस तरह आपको एक अर्ध यादृच्छिक संख्या प्राप्त होगी (जैसे DateTime.Now.Ticks
) इसे एक चर में संग्रहीत करें, फिर जब आप सूची से गुजरना शुरू करेंगे तो आप मूल बीज का उपयोग करके एक नया यादृच्छिक उदाहरण बनाएंगे:
private static int randSeed = (int)DateTime.Now.Ticks; //Must stay the same unless you want to get different random numbers.
private static Random GetNewRandomIterator()
{
return new Random(randSeed);
}
यह ध्यान रखना महत्वपूर्ण है कि जबकि फ्रेड्रिक मोर्क के उत्तर से जुड़ा ब्लॉग इंगित करता है कि मुद्दा आमतौर पर पते की जगह की कमी के कारण है, यह 2 जीबी सीएलआर ऑब्जेक्ट आकार सीमा (जैसे टिप्पणी में उल्लिखित) जैसे कई अन्य मुद्दों को सूचीबद्ध नहीं करता है। ShuggyCoUk एक ही ब्लॉग पर), स्मृति विखंडन पर चमकता है, और पृष्ठ फ़ाइल आकार के प्रभाव का उल्लेख करने में विफल रहता है (और इसे CreateFileMapping
फ़ंक्शन के उपयोग के साथ कैसे संबोधित किया जा सकता है )।
2GB की सीमा का मतलब randomNumbers
2GB से कम होना चाहिए। चूंकि सरणियाँ कक्षाएं हैं और कुछ ओवरहेड हैं, इसलिए वे इसका मतलब है कि एक सरणी को double
2 ^ 31 से छोटा होना होगा। मुझे यकीन नहीं है कि तब 2 ^ 31 की लंबाई कितनी छोटी होगी, लेकिन एक .NET सरणी का ओवरहेड? 12 - 16 बाइट्स इंगित करता है।
मेमोरी विखंडन एचडीडी विखंडन के समान है। आपके पास 2GB पता स्थान हो सकता है, लेकिन जैसा कि आप ऑब्जेक्ट बनाते हैं और नष्ट करते हैं, मूल्यों के बीच अंतराल होगा। यदि ये अंतराल आपकी बड़ी वस्तु के लिए बहुत छोटे हैं, और अतिरिक्त स्थान का अनुरोध नहीं किया जा सकता है, तो आपको यह मिल जाएगाSystem.OutOfMemoryException
। उदाहरण के लिए, यदि आप 2 मिलियन, 1024 बाइट ऑब्जेक्ट बनाते हैं, तो आप 1.9GB का उपयोग कर रहे हैं। यदि आप प्रत्येक ऑब्जेक्ट को हटाते हैं, जहां पता 3 से अधिक नहीं है, तो आप .6GB मेमोरी का उपयोग कर रहे होंगे, लेकिन यह 2024 बाइट ओपन ब्लॉक्स के साथ एड्रेस स्पेस में फैल जाएगा। यदि आपको कोई ऐसी वस्तु बनाने की आवश्यकता है जो .2GB थी तो आप इसे नहीं कर पाएंगे क्योंकि इसमें फिट होने के लिए एक बड़ा ब्लॉक नहीं है और अतिरिक्त स्थान प्राप्त नहीं किया जा सकता है (32 बिट वातावरण मानकर)। इस समस्या का संभावित समाधान छोटी वस्तुओं का उपयोग करना, स्मृति में आपके द्वारा संग्रहीत डेटा की मात्रा को कम करना या स्मृति विखंडन को रोकने / रोकने के लिए मेमोरी प्रबंधन एल्गोरिथ्म का उपयोग करने जैसी चीजें हैं। यह ध्यान दिया जाना चाहिए कि जब तक आप एक बड़े कार्यक्रम को विकसित नहीं कर रहे हैं जो बड़ी मात्रा में मेमोरी का उपयोग करता है यह एक मुद्दा नहीं होगा। इसके अलावा,
चूंकि अधिकांश प्रोग्राम ओएस से काम करने की मेमोरी का अनुरोध करते हैं और फ़ाइल मैपिंग का अनुरोध नहीं करते हैं, वे सिस्टम की रैम और पेज फ़ाइल आकार द्वारा सीमित होंगे। जैसा कि ब्लॉग पर Néstor Sánchez (Néstor Sánchez) की टिप्पणी के अनुसार C # जैसे प्रबंधित कोड के साथ आप RAM / पृष्ठ फ़ाइल सीमा और ऑपरेटिंग सिस्टम के एड्रेस स्पेस से चिपके हुए हैं।
इस तरह अब और उम्मीद की जा रही थी। उम्मीद है कि यह किसी की मदद करता है। मैंने इसे पोस्ट किया क्योंकि मैं System.OutOfMemoryException
24GB RAM के साथ एक सिस्टम पर x64 प्रोग्राम चला रहा था, हालांकि मेरी सरणी केवल 2GB सामान रखने की थी।