2017-04-07 6 views
6

मैं इस प्रकार जावा में 2 डी सरणी बनाने के लिए कोशिश कर रहा हूँ:अधिकतम सीमा

int[][] adjecancy = new int[96295][96295]; 

लेकिन यह निम्न त्रुटि के साथ विफल हो रहा है:

JVMDUMP039I Processing dump event "systhrow", detail "java/lang/OutOfMemoryError" at 2017/04/07 11:58:55 - please wait. 
JVMDUMP032I JVM requested System dump using 'C:\eclipse\workspaces\TryJavaProj\core.20170407.115855.7840.0001.dmp' in response to an event 
JVMDUMP010I System dump written to C:\eclipse\workspaces\TryJavaProj\core.20170407.115855.7840.0001.dmp 
JVMDUMP032I JVM requested Heap dump using 'C:\eclipse\workspaces\TryJavaProj\heapdump.20170407.115855.7840.0002.phd' in response to an event 
JVMDUMP010I Heap dump written to C:\eclipse\workspaces\TryJavaProj\heapdump.20170407.115855.7840.0002.phd 

हल करने के लिए इस से है एक तरह से जेवीएम मेमोरी बढ़ाना लेकिन मैं ऑनलाइन कोडिंग चुनौती के लिए कोड जमा करने की कोशिश कर रहा हूं। वहां भी यह असफल रहा है और मैं वहां सेटिंग्स को बदलने में सक्षम नहीं होगा।

क्या बड़े सरणी बनाने के लिए कोई मानक सीमा या मार्गदर्शन है जो किसी से अधिक नहीं होना चाहिए?

+2

क्या यह 2 डी सरणी होना चाहिए? – stholzm

+3

आप 37 जीबी मेमोरी आवंटित करने की कोशिश कर रहे हैं। यह काफी है और यहां तक ​​कि बढ़ती जेवीएम मेमोरी के साथ एक बड़ी मशीन की आवश्यकता होगी। आपको एक स्मार्ट एल्गोरिदम खोजने की आवश्यकता है (यही कारण है कि इसे कोडिंग चुनौती कहा जाता है) – Henry

+1

आप पूछ रहे हैं कि 40 जीबी मेमोरी का उपयोग किये बिना 40 जीबी मेमोरी आवंटित करना संभव है? नहीं यह नहीं। यदि आप हमें बताते हैं * क्यों * आप ऐसा करने की कोशिश कर रहे हैं, शायद हम आपके समाधान को बेहतर बनाने में मदद कर सकते हैं। – shmosel

उत्तर

13
int[][] adjecancy = new int[96295][96295]; 

जब आप है कि आप 96525*96525*32 बिट्स जो लगभग 37091 MB है जो लगभग 37 gigs है आवंटित करने के लिए कोशिश कर रहे हैं है। अकेले जावा के लिए पीसी से स्मृति प्राप्त करना बेहद असंभव है।

मुझे नहीं लगता कि आपको अपने कार्यक्रम के आरंभ पर अपने हाथ में इतना अधिक डेटा चाहिए। शायद आपको ArrayList को देखना होगा जो आपको आकार के गतिशील आवंटन देता है और फिर रनटाइम पर मुक्त होने पर विचार करना महत्वपूर्ण है।

कोई सरणी बनाने के लिए कोई सीमा या प्रतिबंध नहीं है। जब तक आपके पास स्मृति हो, तब तक आप इसका उपयोग कर सकते हैं। लेकिन ध्यान रखें कि आपको स्मृति की एक ब्लॉक नहीं रखनी चाहिए जो जेवीएम जीवन को व्यस्त बनाता है।

+0

गणना में मेरा बुरा - सही। –

0

यह आपके जेवीएम और सरणी के सामग्री प्रकार के लिए उपलब्ध अधिकतम मेमोरी पर निर्भर करता है। Int के लिए हमारे पास स्मृति के 4 बाइट हैं। अब अगर आपकी मशीन पर 1 एमबी मेमोरी उपलब्ध है, तो इसमें अधिकतम 1024 * 256 पूर्णांक (1 एमबी = 1024 * 1024 बाइट्स) हो सकते हैं। इसे ध्यान में रखते हुए आप तदनुसार अपना 2 डी सरणी बना सकते हैं।

1

अधिकतम हेप आकार आवंटित करने की अनुशंसा की जाती है जिसे आवंटित किया जा सकता है मशीन रैम आकार का 1/4 वां।

जावा में 1 int 4 बाइट लेता है और आपके सरणी आवंटन को लगभग 37.0 9 जीबी मेमोरी की आवश्यकता होती है।

उस मामले में यदि मुझे लगता है कि आप केवल एक ऐरे के लिए पूर्ण ढेर आवंटित कर रहे हैं तो आपकी मशीन लगभग 148 जीबी रैम होनी चाहिए। वह बहुत बड़ा है।

नीचे एक नज़र डालें।

रेफरी: http://docs.oracle.com/javase/8/docs/technotes/guides/vm/gc-ergonomics.html

आशा इस मदद करता है।

0

ऐरे जिसे आप बना सकते हैं JVM ढेर आकार पर निर्भर करता है।

96295 * 96295 * 4 (बाइट प्रति संख्या) = 37,090,908,100 बाइट = ~ 34.54 GBytes। प्रतिस्पर्धी कोड न्यायाधीशों में अधिकांश जेवीएम में इतनी मेमोरी नहीं है। इसलिए त्रुटि।

Scanner scanner = new Scanner(System.in); 
    while(true){ 
     System.out.println("Enter 2-D array of size: "); 
     size = scanner.nextInt(); 

     int [][]numbers = new int[size][size]; 
     numbers = null; 
    } 

उदहारण के लिए: भागो अलग -Xmx सेटिंग्स के साथ इस कोड स्निपेट -

क्या सरणी आकार दी ढेर आकार के लिए उपयोग कर सकते हैं का एक अच्छा विचार प्राप्त करने के -एक्सएमएक्स 512 एम -> 2-डी तत्वों के 2-डी सरणी के साथ।

आम तौर पर अधिकांश ऑनलाइन न्यायाधीशों में सबमिशन का मूल्यांकन करते समय ~ 1.5-2GB ढेर है।

+0

@ हेनरी - गलती को सुधारने के लिए धन्यवाद। –

3

ऐरे स्पष्ट रूप से स्मृति में फिट होना चाहिए। ऐसा नहीं होता है, ठेठ समाधान हैं:

  • तुम सच में int (अधिकतम मूल्य 2,147,483,647) की ज़रूरत है? शायद byte (अधिकतम मूल्य 127) या short पर्याप्त है? byteint से 8 गुना छोटा है।
  • क्या आपके पास सरणी में वास्तव में कई समान मान हैं (जैसे शून्य)? स्पैर सरणी का उपयोग करने की कोशिश करें।
उदाहरण के लिए

:

Map<Integer, Map<Integer, Integer>> map = new HashMap<>(); 
map.put(27, new HashMap<Integer, Integer>()); // row 27 exists 
map.get(27).put(54, 1); // row 27, column 54 has value 1. 

वे संग्रहीत मूल्य प्रति अधिक स्मृति की जरूरत है, लेकिन मूल रूप से सरणी अंतरिक्ष पर कोई सीमा नहीं है (यदि आप सूचकांक के रूप में लंबे समय से नहीं बल्कि पूर्णांक से उपयोग करने के लिए उन्हें वास्तव में बहुत बड़ा बनाने के लिए कर सकते हैं)।

  • शायद आप नहीं जानते कि सरणी कब तक होनी चाहिए? ArrayList आज़माएं, यह स्वयं का आकार बदलता है। 2 डी सरणी के लिए ArrayLists के ArrayList का उपयोग करें।

  • यदि कुछ और उपयोगी नहीं है, तो RandomAccessFile का उपयोग अपने सिस्टम को फाइल सिस्टम में संग्रहीत करने के लिए करें। 100 जीबी या किसी भी अच्छे वर्कस्टेशन पर इन समस्याओं में कोई समस्या नहीं है, आपको बस फ़ाइल में आवश्यक ऑफ़सेट की गणना करने की आवश्यकता है। फाइल सिस्टम स्पष्ट रूप से रैम की तुलना में बहुत धीमी है लेकिन अच्छी एसएसडी ड्राइव के साथ सहनशील हो सकता है।

+1

मुझे यह उत्तर बहुत पसंद है, क्योंकि यह न केवल स्पष्ट बताता है, बल्कि चुनौती को खराब किए बिना कई संभावित समाधानों को भी रेखांकित करता है। इस चुनौती के लिए शायद एक चाल है, जैसे एक स्पैर मैट्रिक्स के लिए एक और स्मृति-कुशल प्रतिनिधित्व। – stholzm

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