स्मृति में सबसे बड़ा पूर्णांक सरणी रखने के लिए आवश्यक स्थान

Jan 04 2021

मैं एक एल्गोरिथ्म की समीक्षा कर रहा हूं और यह एक पूर्णांक बनाता है, इनपुट का आकार गतिशील है। तो मेरी गणना के अनुसार यह जितना हो सकता है

  integer MAX_VALUE  * int size  = ?   
      2^31 integers  * 4 bytes   = ?
2147483648 integers  * 4 bytes   = 8 Gigabytes

क्या यह गणना सही है? JVM int सरणी को स्टोर करने के लिए इस अधिक सन्निहित स्थान का उपयोग करेगा या क्या अन्य चीजें हैं जिन पर विचार करने की आवश्यकता है?

जवाब

3 Eugene Jan 05 2021 at 01:39

सरणी का सैद्धांतिक आकार होगा:

  • 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 बाइट्स पैडिंग
1 BasilBourque Jan 04 2021 at 15:23

सरणी आकार अधिकतम < Integer.MAX_VALUE

नहीं, आपका अधिकतम गलत है।

जावा में एक सरणी में तत्वों की संख्या की सीमा Integer.MAX_VALUE(2,147,483,647) की तुलना में थोड़ी कम है , जावा, होस्ट ओएस और कैसे जावा संकलित किया गया था, इसके संस्करण पर निर्भर करता है। इवान ममोनतोव के इस उत्तर को प्रश्न पर देखें , मैं बड़े आकार के साथ एक सरणी क्यों नहीं बना सकता हूं? ।

हाँ, intigs 8 गिग्स का सबसे बड़ा सरणी

तो अधिकतम सरणी का आकार intमोटे तौर पर ( Integer.MAX_VALUE - 8L ) * 32Lबिट्स होगा जो 68,719,476,448 बिट्स है जो 8,589,934,556 ऑक्टेट है।

तो हाँ, स्मृति के लगभग 8 gigs। और याद रखें: यह एक सरणी के लिए सन्निहित स्मृति है। इसलिए:

  • JVM और होस्ट OS की ओर से इस तरह के एक सरणी का निर्माण करने के लिए महत्वपूर्ण काम हो सकता है, जो कि रनटाइम के दौरान उस समय स्मृति कितनी विखंडित है।
  • यदि होस्ट हार्डवेयर में पर्याप्त वास्तविक मेमोरी नहीं है, तो आप वर्चुअल मेमोरी में लैपिंग करेंगे जहां परिणामी पेजिंग से भयानक प्रदर्शन हो सकता है।

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