क्या जावा सरणियों का अधिकतम आकार है?


214

क्या जावा सरणी में तत्वों की संख्या की कोई सीमा हो सकती है? यदि ऐसा है, तो ये क्या है?


5
आपने एक गलत उत्तर स्वीकार कर लिया है, बस इतनी लंबी सरणी आवंटित करने का प्रयास करें (और नहीं, मैं स्मृति से बाहर नहीं चल रहा हूं)।
मआर्टिनस


जवाबों:


184

सही जवाब नहीं देखा, भले ही यह परीक्षण करना बहुत आसान है।

हाल ही में हॉटस्पॉट वीएम में, सही उत्तर है 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

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

7
क्या आपको पता है कि यह आपको उन पांच बाइट्स क्यों नहीं देगा? क्या यह जरूरी चीज है जो हमेशा जावा में होती है, या यह सिर्फ आपके कंप्यूटर की मेमोरी या किसी चीज से संबंधित हो सकती है?
तैमून

17
@ केविन बॉरिलियन: ऐसा लगता है कि ओरेकल 1.7.0_07 का उपयोग करके बदल गया है, मैं MAX_VALUE-2तत्वों को आवंटित कर सकता हूं । यह वह चीज है जो मैं आवंटित करता हूं, और मैं वास्तव में आश्चर्यचकित हूं कि क्या वीएम दो "चीजों" का उपयोग कर सकता है (लंबाई 2 बाइट्स में फिट नहीं होती है)।
मआर्टिनस

3
@ TomášZato में नवीनतम Integer.MAX_VALUE+1, आपके पास एक पूर्णांक अतिप्रवाह होगा। जावा में सरणी आकार हैं int, नहीं long; कोई फर्क नहीं पड़ता कि आप अपने सरणी, बाइट्स या संदर्भों में कौन सा डेटा स्टोर करते हैं। स्ट्रिंग्स सिर्फ ऑब्जेक्ट रेफरेंस हैं।
QUIT - Anony-Mousse

8
JDK 6 और इसके बाद के संस्करण में एक सरणी में तत्वों की अधिकतम संख्या Integer.MAX_VALUE - 2= 2 147 483 645 है। जावा इस तरह के एक सरणी को सफलतापूर्वक आवंटित करता है यदि आप इसे चलाते हैं -Xmx13GOutOfMemoryError: Java heap spaceयदि आप पास हो जाते हैं तो यह विफल हो जाता है -Xmx12G
एलेक्सी इवानोव

127

यह (निश्चित रूप से) पूरी तरह से वीएम-निर्भर है।

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?
जॉनवेन्थ

@Pacerier। क्या यह MAX_ARRAY_SIZE केवल तब ही लागू नहीं किया जाना चाहिए जब आप किसी ArrayList का उपयोग कर रहे हों? यह int [] array = new int [some_value_here] जैसे किसी सरणी का उपयोग करने से अलग है; है ना? ArrayList में एक निरंतर परिभाषित एक सामान्य सरणी ([] के साथ परिभाषित) पर क्यों लागू किया जा सकता है? क्या वे पर्दे के पीछे ही हैं?
टियागो

1
@Tiago, नहीं, कोड को केवल सरणियों के अधिकतम आकार से कोई लेना-देना नहीं है। यह सिर्फ एक दावा है।
पचेरियर

@ जॉनहॉर्न, बोली में कहा गया है "कुछ वीएम एक सरणी में कुछ हेडर शब्द आरक्षित करते हैं"। इसलिए -8बाइट्स के कारण आरक्षित हेडर शब्दों पर कब्जा कर लेंगे।
पचेरियर

38

वास्तव में दो सीमाएँ हैं। एक, सरणी और, दो, आपके आवेदन के लिए उपलब्ध स्मृति की मात्रा के लिए अनुक्रमित अधिकतम तत्व। उपलब्ध स्मृति की मात्रा और अन्य डेटा संरचनाओं द्वारा उपयोग की जाने वाली राशि के आधार पर, अधिकतम पता योग्य सरणी तत्व तक पहुँचने से पहले आप मेमोरी सीमा पर प्रभाव डाल सकते हैं।


27

इस लेख के द्वारा जा रहे हैं http://en.wikipedia.org/wiki/Criticism_of_Java#Large.arr :

जावा को 2 31 about1 (लगभग 2.1 बिलियन) से अधिक के सरणियों का समर्थन नहीं करने के लिए आलोचना की गई है । यह भाषा की एक सीमा है; जावा भाषा विशिष्टता, धारा १०.४, बताती है कि:

सरणी को अंतर मानों द्वारा अनुक्रमित किया जाना चाहिए ... एक संकलन-समय त्रुटि में एक लंबे अनुक्रमणिका मान परिणाम के साथ एक सरणी घटक तक पहुंचने का प्रयास।

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


6
जावा में बहुआयामी सरणियों के लिए सिंटैक्टिक शुगर का अभाव है, लेकिन आप अभी भी "उन्हें" थोड़ा गुणा कर सकते हैं (जब तक कि सरणी का कुल आकार पूर्वोक्त सीमा से अधिक न हो जाए)
kbolino

11

सरणी गैर-नकारात्मक पूर्णांक अनुक्रमित हैं, इसलिए अधिकतम सरणी आकार जो आप एक्सेस कर सकते हैं 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पास कितनी मेमोरी है और उसमें से कितनी अन्य वस्तुओं को पहले ही आवंटित की जा चुकी है।


3

मैंने इस तरह से एक बाइट सरणी बनाने की कोशिश की

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

हाँ, जावा सरणी पर सीमा है। जावा सरणी के सूचकांक के रूप में एक पूर्णांक का उपयोग करता है और जेवीएम द्वारा अधिकतम पूर्णांक स्टोर 2 ^ 32 है। तो आप सरणी में 2,147,483,647 तत्व संग्रहीत कर सकते हैं।

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


1

एक के तत्वों की अधिकतम संख्या arrayहै (2^31)−1या2 147 483 647


5
जावा आकार की सरणी आवंटित नहीं कर सकता है Integer.MAX_VALUE - 1, आपको "java.lang.OutOfMemoryError: आवश्यक सरणी आकार VM सीमा से अधिक है" मिलेगा। JDK 6 और उसके बाद के तत्वों की अधिकतम संख्या Integer.MAX_VALUE - 2= 2 147 483 645 है।
एलेक्सी इवानोव

0

वास्तव में यह जावा सीमा है इसे 2 ^ 30-4 पर कैप करके 1073741820 किया जा रहा है। 2 ^ 31-1 नहीं। क्यों नहीं, लेकिन मैंने इसे मैन्युअल रूप से jdk पर परीक्षण किया है। 2 ^ 30-3 अभी भी वीएम को छोड़कर

संपादित करें: फिक्स्ड -1 से -4, विंडोज़ जेवीएम पर जाँच की गई


आप 32-बिट JVM का उपयोग कर रहे हैं। 64-बिट JVM का उपयोग करें और JVM की सीमा 2 ^ 31 के करीब होगी। (आपको उपलब्ध स्थान की भी आवश्यकता है, जो डिफ़ॉल्ट नहीं है, और आपकी भौतिक स्मृति से प्रभावित होगा।)
dave_thompson_085
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.