स्मृति में सबसे बड़ा पूर्णांक सरणी रखने के लिए आवश्यक स्थान
मैं एक एल्गोरिथ्म की समीक्षा कर रहा हूं और यह एक पूर्णांक बनाता है, इनपुट का आकार गतिशील है। तो मेरी गणना के अनुसार यह जितना हो सकता है
integer MAX_VALUE * int size = ?
2^31 integers * 4 bytes = ?
2147483648 integers * 4 bytes = 8 Gigabytes
क्या यह गणना सही है? JVM int सरणी को स्टोर करने के लिए इस अधिक सन्निहित स्थान का उपयोग करेगा या क्या अन्य चीजें हैं जिन पर विचार करने की आवश्यकता है?
जवाब
सरणी का सैद्धांतिक आकार होगा:
numberOfElementsInTheArray * 4 बाइट्स
हेडर के 12 बाइट्स (
int[]
एक वस्तु है)। दरअसल हेडर का आकार आपके द्वारा उपयोग किए जाने वाले झंडे और आपके द्वारा चलाए जा रहे जेवीएम संस्करण पर निर्भर करता हैlength
सरणी रखने के लिए 4 बाइट्सगद्दी।
उदाहरण के लिए: (मैं इसके लिए JOL का उपयोग करने जा रहा हूं ):
int [] x = new int[10];
for(int i=0;i<10;++i){
x[i] = 9999;
}
System.out.println(GraphLayout.parseInstance((Object)x).toPrintable());
उत्पादन होगा:
[I@7a81197dd object externals:
ADDRESS SIZE TYPE PATH VALUE
70fe45268 56 [I [9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999]
तो यह है 56 bytes
:
- स्वयं मानों के लिए 40 (10 इंच * 4 बाइट्स)
- हेडर के लिए 12
- लंबाई के लिए 4
- पैडिंग के लिए 0
यदि आप इस सरणी को Integer
बदलते हैं, तो चीजें नाटकीय रूप से बदल जाती हैं। Integer
एक वस्तु है, इसलिए आप सरणी के अंदर एक संदर्भ संग्रहीत करेंगे (जो ध्वज के आधार पर 4
या 8
बाइट्स हो सकता है UseCompressedOops
), प्लस प्रत्येक Integer
उदाहरण में 2 हेडर (प्रत्येक Integer
एक ऑब्जेक्ट है) की आवश्यकता होगी ।
Integer[] y = new Integer[10];
for(int i=0;i<10;++i){
y[i] = 9999;
}
System.out.println(GraphLayout.parseInstance((Object)y).toFootprint());
जो दिखाएगा:
[Ljava.lang.Integer;@369f73a2d footprint:
COUNT AVG SUM DESCRIPTION
1 56 56 [Ljava.lang.Integer;
10 16 160 java.lang.Integer
11 216 (total)
कुल 216 bytes
:
- प्रत्येक संदर्भ के लिए 4 बाइट्स (मैंने
UseCompressedOop
चालू किया है), कुल 40 बाइट्स - सरणी के 12 बाइट्स हेडर
- सरणी की लंबाई 4 बाइट्स
- 0 बाइट्स पैडिंग
उस एरे से प्रत्येक संदर्भ एक को इंगित करता है Integer
, उन वस्तुओं में से प्रत्येक में होगा 16 bytes
:
- 4 बाइट्स आंतरिक के लिए
int
वे रखती हैं - 12 बाइट्स हेडर
- 0 बाइट्स पैडिंग
सरणी आकार अधिकतम < Integer.MAX_VALUE
नहीं, आपका अधिकतम गलत है।
जावा में एक सरणी में तत्वों की संख्या की सीमा Integer.MAX_VALUE(2,147,483,647) की तुलना में थोड़ी कम है , जावा, होस्ट ओएस और कैसे जावा संकलित किया गया था, इसके संस्करण पर निर्भर करता है। इवान ममोनतोव के इस उत्तर को प्रश्न पर देखें , मैं बड़े आकार के साथ एक सरणी क्यों नहीं बना सकता हूं? ।
हाँ, int
igs 8 गिग्स का सबसे बड़ा सरणी
तो अधिकतम सरणी का आकार int
मोटे तौर पर ( Integer.MAX_VALUE - 8L ) * 32L
बिट्स होगा जो 68,719,476,448 बिट्स है जो 8,589,934,556 ऑक्टेट है।
तो हाँ, स्मृति के लगभग 8 gigs। और याद रखें: यह एक सरणी के लिए सन्निहित स्मृति है। इसलिए:
- JVM और होस्ट OS की ओर से इस तरह के एक सरणी का निर्माण करने के लिए महत्वपूर्ण काम हो सकता है, जो कि रनटाइम के दौरान उस समय स्मृति कितनी विखंडित है।
- यदि होस्ट हार्डवेयर में पर्याप्त वास्तविक मेमोरी नहीं है, तो आप वर्चुअल मेमोरी में लैपिंग करेंगे जहां परिणामी पेजिंग से भयानक प्रदर्शन हो सकता है।
हमेशा वास्तविक दुनिया के परीक्षण करें यदि आप वास्तव में अपने काम में इन सीमाओं को आगे बढ़ा रहे हैं। और आप बहुत बड़ी मेमोरी के लिए डिज़ाइन किए गए जावा के वैकल्पिक कार्यान्वयन पर विचार करना चाह सकते हैं, जैसे कि अज़ल सिस्टम द्वारा ज़िंग ।