2010-09-07 9 views
31

का परीक्षण करता है, मैं परीक्षण कर रहा हूं कि संग्रह में कितना बड़ा संग्रह हो सकता है। नेट। तकनीकी रूप से, कोई संग्रह वस्तु भौतिक स्मृति के आकार में बढ़ सकती है।.NET में बहुत बड़ा संग्रह आउट-ऑफ-मेमोरी अपवाद

फिर मैंने निम्नलिखित कोड का परीक्षण एक सेवर में किया, जिसमें 16 जीबी मेमोरी है, विंडोज 2003 सर्वर और विजुअल स्टूडियो 2008 चल रहा है। मैंने एफ # और सी # कोड दोनों का परीक्षण किया, और चलते समय टास्क मैनेजर को देखा। मैं देख सकता हूं कि 2 जीबी मेमोरी बढ़ने के बाद, प्रोग्राम आउट-ऑफ-मेमोरी अपवाद के साथ दुर्घटनाग्रस्त हो गया। मैंने प्रॉपर्टी पेज में लक्ष्य प्लेटफ़ॉर्म को x64 पर सेट किया था।

open System.Collections.Generic 

let d = new Dictionary<int, int>() 

for i=1 to 1000000000 do 
    d.Add(i,i) 

मैंने C5 संग्रह पुस्तकालय में एक ही परीक्षण किया था। नतीजा यह है कि सी 5 में शब्दकोश पूरी मेमोरी का उपयोग कर सकता है। कोड सी 5:

let d = C5.HashDictionary<int, int>() 
for i=1 to 1000000000 do 
    d.Add(i,i) 

कोई भी जानता है क्यों?

+12

शारीरिक स्मृति जो भी कुछ भी नहीं अधिकतम आकार के साथ क्या करना है देखते हैं। विंडोज़ ने एक दशक से अधिक समय तक वर्चुअल मेमोरी प्रबंधन का उपयोग किया है। आपके पास ऐसी ऑब्जेक्ट्स हो सकती हैं जो उपलब्ध भौतिक स्मृति से कहीं अधिक बड़ी हैं, क्योंकि निश्चित रूप से उपलब्ध होने पर भौतिक स्मृति * शून्य * हो सकती है जब एक नई प्रक्रिया बनाई जाती है। वर्चुअल मेमोरी का यह पूरा * बिंदु * है; कि भौतिक स्मृति वर्चुअल मेमोरी का एक प्रदर्शन अनुकूलन है। (यदि काम करने वाले सेट को रखने के लिए पर्याप्त भौतिक स्मृति नहीं है तो प्रदर्शन घटता है, लेकिन सबकुछ अभी भी * काम * होना चाहिए।) –

+2

@EricLippert समझा और सहमत हो गया लेकिन रिवर्स के बारे में क्या ... क्या आपको कभी भी ओओएम मिलना चाहिए जब भौतिक स्मृति हो उपलब्ध? (मान लीजिए कि यह एक वास्तविक ओओएम है जो बहुत अधिक हैंडल/समान समस्या नहीं है)। इस उदाहरण में, ऐसा लगता है कि सीएलआर-लगाई गई सीमा मुद्दा थी, लेकिन इसका मतलब है कि ओपीएस प्रश्न मेरी राय – Basic

उत्तर

42

माइक्रोसॉफ्ट सीएलआर में 2 जीबी अधिकतम ऑब्जेक्ट आकार सीमा है, यहां तक ​​कि 64 बिट संस्करण भी है। (मुझे यकीन नहीं है कि यह सीमा मोनो जैसे अन्य कार्यान्वयन में भी मौजूद है।)

सीमा प्रत्येक एकल ऑब्जेक्ट पर लागू होती है - सभी ऑब्जेक्ट्स का कुल आकार नहीं - जिसका अर्थ है कि यह अपेक्षाकृत आसान है किसी प्रकार के समग्र संग्रह का उपयोग करके कामकाज करने के लिए।

वहाँ एक चर्चा और यहाँ कुछ उदाहरण कोड है ...

बहुत कम आधिकारिक दस्तावेज है कि इस सीमा को संदर्भित करता है लगता है। यह, वर्तमान सीएलआर के केवल एक कार्यान्वयन विस्तार है। केवल उल्लेख नहीं है कि मैं के बारे में पता कर रहा हूँ on this page है:

जब आप चलाने के एक 64-बिट एक 64-बिट Windows ऑपरेटिंग सिस्टम पर आवेदन में कामयाब रहे हैं, तो आप अधिक से अधिक 2 गीगाबाइट की एक वस्तु बना सकते हैं (जीबी)।

+0

+1 में एक अच्छा है, @Yin: यह आलेख आपको http: // ब्लॉगों के आसपास जाने में मदद कर सकता है। msdn.com/b/joshwil/archive/2005/08/10/450202.aspx –

+0

@KMan: Ha। मैंने संपादित किया कि आपकी टिप्पणी प्रकट होने से कुछ ही सेकंड पहले :) – LukeH

+1

और आपकी पूरी पोस्ट बस मेरे सामने कुछ सेकंड पहले आई :) :) –

10

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

सी 5 हैश डिक्शनरी रैखिक हैशिंग का उपयोग करता है, और संभवतः कई (16?) तत्वों वाले प्रत्येक बाल्टी की सरणी का उपयोग करता है। इसे बाद में एक ही समस्या (बहुत) में चलना चाहिए।

+0

महान टिप्पणी! धन्यवाद। –

+0

बीटीडब्ल्यू, सी 5 में कार्यान्वयन रैखिक श्रृंखला है - प्रत्येक हैश मान के लिए, यह एक लिंक्ड सूची है। –

+0

आह, धन्यवाद। उसके खिलाफ मूल रैखिक हैशिंग पेपर सलाह। –

18

4.5 से पहले .NET के संस्करणों में, अधिकतम ऑब्जेक्ट आकार 2 जीबी है। gcAllowVeryLargeObjects सक्षम होने पर 4.5 से आगे आप बड़ी ऑब्जेक्ट आवंटित कर सकते हैं। ध्यान दें कि string की सीमा प्रभावित नहीं है, लेकिन "सरणी" को "सूचियां" भी शामिल करनी चाहिए, क्योंकि सूचियों को सरणी द्वारा समर्थित किया जाता है।

-1

"बड़ी वस्तुओं को अनुमति दें" केवल ओओएम अपवाद से छुटकारा पाने में मदद करेगा।

जब किसी को बहुत सारी वस्तुओं को स्टोर करने की आवश्यकता होती है तो आप जो समस्या देखेंगे वह जीसी स्टालों (विराम) है।हमने जो किया है वह जीसी से डेटा का "छिपाना" है, जो में एक बहुत ही व्यावहारिक समाधान बन गया है।

इस देखें: https://www.infoq.com/articles/Big-Memory-Part-3

आप कैश है कि एक शब्दकोश के रूप में काम करता है का उपयोग कर सकते हैं: https://github.com/aumcode/nfx/tree/master/Source/NFX/ApplicationModel/Pile

कैशिंग अनुभाग

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