क्या जावा सरणी में तत्वों की संख्या की कोई सीमा हो सकती है? यदि ऐसा है, तो ये क्या है?
क्या जावा सरणी में तत्वों की संख्या की कोई सीमा हो सकती है? यदि ऐसा है, तो ये क्या है?
जवाबों:
सही जवाब नहीं देखा, भले ही यह परीक्षण करना बहुत आसान है।
हाल ही में हॉटस्पॉट वीएम में, सही उत्तर है Integer.MAX_VALUE - 5। एक बार जब आप उससे आगे निकल जाते हैं:
public class Foo {
public static void main(String[] args) {
Object[] array = new Object[Integer.MAX_VALUE - 4];
}
}
आपको मिला:
Exception in thread "main" java.lang.OutOfMemoryError:
Requested array size exceeds VM limit
MAX_VALUE-2तत्वों को आवंटित कर सकता हूं । यह वह चीज है जो मैं आवंटित करता हूं, और मैं वास्तव में आश्चर्यचकित हूं कि क्या वीएम दो "चीजों" का उपयोग कर सकता है (लंबाई 2 बाइट्स में फिट नहीं होती है)।
Integer.MAX_VALUE+1, आपके पास एक पूर्णांक अतिप्रवाह होगा। जावा में सरणी आकार हैं int, नहीं long; कोई फर्क नहीं पड़ता कि आप अपने सरणी, बाइट्स या संदर्भों में कौन सा डेटा स्टोर करते हैं। स्ट्रिंग्स सिर्फ ऑब्जेक्ट रेफरेंस हैं।
Integer.MAX_VALUE - 2= 2 147 483 645 है। जावा इस तरह के एक सरणी को सफलतापूर्वक आवंटित करता है यदि आप इसे चलाते हैं -Xmx13G। OutOfMemoryError: Java heap spaceयदि आप पास हो जाते हैं तो यह विफल हो जाता है -Xmx12G।
यह (निश्चित रूप से) पूरी तरह से वीएम-निर्भर है।
OpenJDK 7 और 8 के स्रोत कोड के माध्यम से ब्राउज़िंग java.util.ArrayList, .Hashtable, .AbstractCollection, .PriorityQueue, और .Vector, आप देख सकते हैं इस दावे को दोहराया जा रहा है:
/** * Some VMs reserve some header words in an array. * Attempts to allocate larger arrays may result in * OutOfMemoryError: Requested array size exceeds VM limit */ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
जो 2010-05-09 को मार्टिन बुचोलज़ (Google) द्वारा जोड़ा गया है ; क्रिस हेगार्टी (ओरेकल) द्वारा समीक्षा की गई।
तो, शायद हम यह कह सकते हैं कि अधिकतम "सुरक्षित" संख्या 2 147 483 639 ( Integer.MAX_VALUE - 8) और "बड़े सरणियों को आवंटित करने के प्रयासों का परिणाम आउटऑफमेरीऑरर " हो सकता है ।
(हां, बुचोलज़ के स्टैंडअलोन दावे में बैकिंग साक्ष्य शामिल नहीं हैं, इसलिए यह प्राधिकरण के लिए एक परिकलित अपील है। ओपनजेडीके के भीतर भी, हम ऐसे कोड को देख सकते हैं, return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;जो दिखाता है कि MAX_ARRAY_SIZEअभी तक इसका वास्तविक उपयोग नहीं हुआ है ।)
-8?
-8बाइट्स के कारण आरक्षित हेडर शब्दों पर कब्जा कर लेंगे।
वास्तव में दो सीमाएँ हैं। एक, सरणी और, दो, आपके आवेदन के लिए उपलब्ध स्मृति की मात्रा के लिए अनुक्रमित अधिकतम तत्व। उपलब्ध स्मृति की मात्रा और अन्य डेटा संरचनाओं द्वारा उपयोग की जाने वाली राशि के आधार पर, अधिकतम पता योग्य सरणी तत्व तक पहुँचने से पहले आप मेमोरी सीमा पर प्रभाव डाल सकते हैं।
इस लेख के द्वारा जा रहे हैं http://en.wikipedia.org/wiki/Criticism_of_Java#Large.arr :
जावा को 2 31 about1 (लगभग 2.1 बिलियन) से अधिक के सरणियों का समर्थन नहीं करने के लिए आलोचना की गई है । यह भाषा की एक सीमा है; जावा भाषा विशिष्टता, धारा १०.४, बताती है कि:
सरणी को अंतर मानों द्वारा अनुक्रमित किया जाना चाहिए ... एक संकलन-समय त्रुटि में एक लंबे अनुक्रमणिका मान परिणाम के साथ एक सरणी घटक तक पहुंचने का प्रयास।
बड़े सरणियों का समर्थन करने के लिए भी जेवीएम में परिवर्तन की आवश्यकता होगी। यह सीमा 2 बिलियन तत्वों तक सीमित होने और मेमोरी मैप फ़ाइलों में असमर्थता जैसे क्षेत्रों में 2 GiB से बड़े क्षेत्रों में ही प्रकट होती है। जावा में वास्तविक बहुआयामी सरणियों का भी अभाव है (एक अप्रत्यक्ष रूप से उपयोग की जाने वाली मेमोरी के एकल ब्लॉक आवंटित किए गए), जो वैज्ञानिक और तकनीकी कंप्यूटिंग के लिए प्रदर्शन को सीमित करता है।
सरणी गैर-नकारात्मक पूर्णांक अनुक्रमित हैं, इसलिए अधिकतम सरणी आकार जो आप एक्सेस कर सकते हैं Integer.MAX_VALUE। दूसरी बात यह है कि आप कितना बड़ा सरणी बना सकते हैं। यह आपके लिए उपलब्ध अधिकतम मेमोरी JVMऔर एरे के कंटेंट टाइप पर निर्भर करता है । प्रत्येक सरणी तत्व का आकार, उदाहरण है। byte = 1 byte, int = 4 bytes,Object reference = 4 bytes (on a 32 bit system)
इसलिए यदि आपके पास 1 MBअपनी मशीन पर उपलब्ध मेमोरी है, तो आप एक सरणी आवंटित कर सकते हैं byte[1024 * 1024]या Object[256 * 1024]।
अपने प्रश्न का उत्तर देना - आप एक सरणी आकार (अधिकतम उपलब्ध स्मृति / सरणी आइटम का आकार) आवंटित कर सकते हैं।
सारांश - सैद्धांतिक रूप से एक सरणी का अधिकतम आकार होगा Integer.MAX_VALUE। व्यावहारिक रूप से यह इस बात पर निर्भर करता है कि आपके JVMपास कितनी मेमोरी है और उसमें से कितनी अन्य वस्तुओं को पहले ही आवंटित की जा चुकी है।
मैंने इस तरह से एक बाइट सरणी बनाने की कोशिश की
byte[] bytes = new byte[Integer.MAX_VALUE-x];
System.out.println(bytes.length);
इस रन कॉन्फ़िगरेशन के साथ:
-Xms4G -Xmx4G
और जावा संस्करण:
Openjdk संस्करण "1.8.0_141"
OpenJDK रनटाइम एनवायरनमेंट (बिल्ड 1.8.0_141-b16)
OpenJDK 64-बिट सर्वर VM (बिल्ड 25.141-b16, मिश्रित मोड)
यह केवल x> = 2 के लिए काम करता है जिसका मतलब है कि किसी सरणी का अधिकतम आकार Integer.MAX_VALUE-2 है
ऊपर दिए गए मान
थ्रेड "मुख्य" java.lang.OutOfMemoryError में अपवाद: अनुरोधित सरणी का आकार VM.m में मुख्य सीमा से अधिक है (Main.java:6)
हाँ, जावा सरणी पर सीमा है। जावा सरणी के सूचकांक के रूप में एक पूर्णांक का उपयोग करता है और जेवीएम द्वारा अधिकतम पूर्णांक स्टोर 2 ^ 32 है। तो आप सरणी में 2,147,483,647 तत्व संग्रहीत कर सकते हैं।
यदि आपको अधिकतम लंबाई से अधिक की जरूरत है तो आप दो अलग-अलग सरणियों का उपयोग कर सकते हैं, लेकिन अनुशंसित विधि डेटा को एक फ़ाइल में संग्रहित करना है। क्योंकि फ़ाइल में डेटा संग्रहीत करने की कोई सीमा नहीं है। क्योंकि आपके भंडारण ड्राइवरों में संग्रहीत फ़ाइलें लेकिन सरणी JVM में संग्रहीत की जाती हैं। जेवीएम कार्यक्रम के निष्पादन के लिए सीमित स्थान प्रदान करता है।
एक के तत्वों की अधिकतम संख्या arrayहै (2^31)−1या2 147 483 647
Integer.MAX_VALUE - 1, आपको "java.lang.OutOfMemoryError: आवश्यक सरणी आकार VM सीमा से अधिक है" मिलेगा। JDK 6 और उसके बाद के तत्वों की अधिकतम संख्या Integer.MAX_VALUE - 2= 2 147 483 645 है।
वास्तव में यह जावा सीमा है इसे 2 ^ 30-4 पर कैप करके 1073741820 किया जा रहा है। 2 ^ 31-1 नहीं। क्यों नहीं, लेकिन मैंने इसे मैन्युअल रूप से jdk पर परीक्षण किया है। 2 ^ 30-3 अभी भी वीएम को छोड़कर
संपादित करें: फिक्स्ड -1 से -4, विंडोज़ जेवीएम पर जाँच की गई