क्यों इंटेगर क्लास कैशिंग वैल्यू -128 से 127 तक में?


81

मेरे पिछले प्रश्न के बारे में, क्यों == Integer.valueOf (स्ट्रिंग) के साथ तुलना 127 और 128 के लिए अलग-अलग परिणाम देते हैं? , हम जानते हैं कि Integer classएक कैश है जो मानों के बीच -128और स्टोर करता है 127

बस सोच रहा था, -128 और 127 के बीच क्यों ?

Integer.valueOf () प्रलेखन ने कहा कि यह " अक्सर अनुरोधित मूल्यों को कैशिंग करता है " । लेकिन क्या मूल्यों के बीच -128और 127अक्सर वास्तविक के लिए अनुरोध किया जाता है? मुझे लगा कि अक्सर अनुरोधित मूल्य बहुत व्यक्तिपरक होते हैं।
क्या इसके पीछे कोई संभावित कारण है?

प्रलेखन से यह भी कहा गया: " .. और इस सीमा के बाहर अन्य मूल्यों को कैश कर सकते हैं। "
यह कैसे प्राप्त किया जा सकता है?


7
दस्तावेज़ीकरण पुन: ओरेकल सिर्फ अपने चूतड़ को कवर कर रहे हैं यदि वे बाद में व्यवहार को बदलने का फैसला करते हैं। उदाहरण के लिए, वे तय कर सकते हैं कि जावा 9 -1024 से 1023 तक कैश करेगा। संदेश है, कैश युक्त या किसी विशिष्ट पूर्णांक पर निर्भर न हों।
दाऊद इब्न करीम

7
मुझे लगता है कि आप 047 से 13476 की तुलना में 0 से X तक अधिक बार लूप करते हैं। उन्होंने तय किया होगा कि नकारात्मक मूल्यों को भी शामिल किया जाना चाहिए और -128 -> 127 एक हस्ताक्षरित बाइट के लिए समझ में आता है।
जीरो वेनवेल

2
लगभग हमेशा w / आदिम चींटियों को लूपिंग नहीं की जाती है - बॉक्सिंग इंटेगर नहीं? कैशिंग लागू नहीं होता है।
ब्रैडविदो

2
कैश विशुद्ध रूप से एक प्रदर्शन की चीज है। जब तक यह आपके लिए एक प्रदर्शन समस्या नहीं बना रहा है, आपको ध्यान नहीं देना चाहिए कि किस सीमा तक कैश किया गया है। (यह आपके कोड में इंटेगर कैशिंग पर निर्भरता बनाने के लिए मूर्खता की ऊंचाई होगी।)
हॉट लिक्स

3
@ जॉनर यह जावा लैंग्वेज के स्पेक्स में है, नीचे दिए गए एसिलियास जवाब देखें।
ज़ैक थॉम्पसन

जवाबों:


105

बस सोच रहा था, -128 और 127 के बीच क्यों?

पूर्णांकों की एक बड़ी श्रृंखला को कैश किया जा सकता है, लेकिन कम से कम -128 और 127 के बीच कैश होना चाहिए क्योंकि यह जावा लैंग्वेज स्पेसिफिकेशन (जोर मेरा) द्वारा अनिवार्य है :

यदि मूल्य p बॉक्सिंग किया जा रहा है तो सही, गलत, एक बाइट, या रेंज में एक char \ u0000 से \ u007f, या -128 और 127 (समावेशी) के बीच एक इंट या शॉर्ट नंबर है , तो r1 और r2 परिणाम दें पी के किसी भी दो मुक्केबाजी रूपांतरण। यह हमेशा ऐसा होता है कि r1 == r2।

इस आवश्यकता के औचित्य को उसी पैराग्राफ में समझाया गया है:

आदर्श रूप से, किसी दिए गए आदिम मूल्य p को बॉक्सिंग करना, हमेशा एक समान संदर्भ देगा । व्यवहार में, मौजूदा कार्यान्वयन तकनीकों का उपयोग करके यह संभव नहीं है। ऊपर दिए गए नियम एक व्यावहारिक समझौता हैं। ऊपर दिए गए अंतिम खंड के लिए आवश्यक है कि कुछ सामान्य मूल्यों को हमेशा अविभाज्य वस्तुओं में रखा जाए। [...]

यह सुनिश्चित करता है कि ज्यादातर सामान्य मामलों में, अनुचित प्रदर्शन दंड लगाए बिना, विशेष रूप से छोटे उपकरणों पर व्यवहार वांछित होगा । उदाहरण के लिए, कम स्मृति-सीमित कार्यान्वयन, सभी चार और लघु मूल्यों को कैश कर सकते हैं, साथ ही -32K से + 32K की सीमा में अंतर और लंबे मूल्य।


मैं इस श्रेणी के बाहर अन्य मूल्यों को कैसे कैश कर सकता हूं।

आप -XX:AutoBoxCacheMaxJVM विकल्प का उपयोग कर सकते हैं , जो वास्तव में उपलब्ध हॉटस्पॉट JVM विकल्प की सूची में प्रलेखित नहीं है । हालांकि यह लाइन 590 के आसपास वर्ग के अंदर टिप्पणियोंInteger में उल्लिखित है :

कैश का आकार -XX:AutoBoxCacheMax=<size>विकल्प द्वारा नियंत्रित किया जा सकता है ।

ध्यान दें कि यह विशिष्ट है और अन्य JVM पर उपलब्ध हो सकता है या नहीं।


2
यह पूर्ण और सबसे अच्छा उत्तर है - प्रश्न -128 -127 से 127 श्रेणी के "अक्सर अनुरोधित मूल्यों" के साथ भ्रमित करता है, जब वास्तव में वे अलग-अलग कारणों से होते हैं। -128 से 127 बॉक्सिंग के लिए कैश हैं। "अक्सर अनुरोधित मूल्य" प्रदर्शन के लिए कैश किए जाते हैं।
Zac थॉम्पसन

@ZacThompson, इसे इंगित करने के लिए धन्यवाद। मेरी पिछली टिप्पणी सही नहीं थी। कल्पना से प्रमुख वाक्यांश "एक इंट ... -128 और 127 (समावेशी) के बीच है, तो आर 1 और आर 2 को पी के किसी भी दो मुक्केबाजी रूपांतरणों के परिणाम हैं। यह हमेशा ऐसा होता है कि आर 1 == आर 2।" इसलिए अगर मैं सही तरीके से समझूं, तो यह आशय बताता है कि Integer.valueOf (X) == Integer.valueOf (X) जहाँ -128 <= X <= 127.
जॉन आर

यह "क्यों" सवाल का हिस्सा है जो "यह डिफ़ॉल्ट है" के अलावा कुछ और प्रदान करता है, का एकमात्र उत्तर है। हालाँकि, यह उत्तर पूर्ण नहीं है क्योंकि यह प्रश्न के "कैसे" भाग को संबोधित नहीं करता है। XX पर दूसरों द्वारा प्रतिक्रियाओं का संदर्भ देना: AutoBoxCacheMax और JVM के अन्य कार्यान्वयन पर कैशिंग व्यवहार को नियंत्रित करने के बारे में जानकारी जोड़ना (या यह दर्शाता है कि JVM कार्यान्वयन के पास इस व्यवहार को नियंत्रित करने के लिए कौन से विकल्प हैं) यह एक पूर्ण उत्तर देगा।
जॉन आर

"व्यवहार में, यह मौजूदा कार्यान्वयन तकनीकों का उपयोग करने के लिए संभव नहीं है।" मुझे यह लाइन नहीं मिल रही है। क्या आप इसे समझा सकते हैं?
नीरज874u

2
@ niiraj874u वर्तमान कार्यान्वयन कैश का उपयोग करता है जो मेमोरी में रहता है - प्रत्येक "कैनॉनिकल" पूर्णांक उस कैश में होता है। इसलिए सभी पूर्णांकों को कैशिंग करने का मतलब होगा कि आपको मेमोरी में 2 ^ 32 पूर्णांक (= 15+ जीबी) तक रखना पड़ सकता है, जो एक आधुनिक डेस्कटॉप कंप्यूटर पर भी अनुचित है।
अस्वच्छता १५'१४ को

22

-128 से 127 डिफ़ॉल्ट आकार है। लेकिन javadoc का यह भी कहना है कि Integer cache का आकार विकल्प द्वारा नियंत्रित किया जा सकता है-XX:AutoBoxCacheMax=<size> । ध्यान दें कि यह केवल उच्च मूल्य निर्धारित करता है, कम मूल्य हमेशा -128 है। यह फीचर 1.6 में पेश किया गया था।

क्यों -128 से 127 तक के लिए - यह बाइट वैल्यू रेंज है और इसे बहुत कम कैश के लिए इस्तेमाल करना स्वाभाविक है।


हम कैसे लागू कर सकते हैं -XX:AutoBoxCacheMax=<size>?
DnR

चलाने जावा -XX: AutoBoxCacheMax = 256 ... और आप देखेंगे Integer.valueOf (256) == Integer.valueOf (256) है कि
एव्गेनि Dorofeev

java -XX:AutoBoxCacheMax=256सांत्वना में दौड़कर , मुझे मिलाError:could not create the Java Virtual Machine
DnR

जावा की कोशिश करो, यह 1.6 या उच्चतर होना चाहिए, मेरे 1.7 काम ठीक है
एवगेनी डोरोफेव

2
ठीक है, यह है कहते हैं क्यों जावाडोक से नियंत्रित किया जा ..may ... मेरे जावा 64 बिट्स है
एव्गेनि Dorofeev

5

छोटे पूर्णांकों को रोकने का कारण, यदि आप जो पूछ रहे हैं, वह यह है कि कई एल्गोरिदम अपनी गणना में छोटे पूर्णांकों का उपयोग करते हैं, इसलिए इन मूल्यों के लिए ऑब्जेक्ट-निर्माण ओवरहेड से बचना सार्थक हो जाता है।

फिर सवाल यह हो जाता है कि कौन से इंजीर को कैश करना है। फिर से, सामान्य रूप से बोलते हुए, आवृत्ति जिसके साथ निरंतर मूल्यों का उपयोग किया जाता है, निरंतर वृद्धि के निरपेक्ष मूल्य के रूप में घट जाती है - हर कोई मान 1 या 2 या 10 का उपयोग करते हुए बहुत समय बिताता है, अपेक्षाकृत कुछ मूल्य 109 का बहुत उपयोग करते हैं तीव्रता से; कम पर प्रदर्शन इस बात पर निर्भर करेगा कि 722 के लिए इंटर्जेक्टर कितनी जल्दी प्राप्त कर सकता है .. जावा ने हस्ताक्षरित बाइट मान की सीमा के साथ 256 स्लॉट आवंटित करने का विकल्प चुना। इस निर्णय को समय पर अस्तित्व में कार्यक्रमों का विश्लेषण करके सूचित किया जा सकता है, लेकिन जैसा कि विशुद्ध रूप से एक मनमाना रहा है। यह निवेश करने के लिए एक उचित स्थान है, इसे तेजी से एक्सेस किया जा सकता है (यह पता लगाने के लिए कि कैश की सीमा में मूल्य है, तो कैश तक पहुंचने के लिए एक त्वरित तालिका लुकअप), और यह निश्चित रूप से सबसे आम मामलों को कवर करेगा।

दूसरे शब्दों में, मुझे लगता है कि आपके प्रश्न का उत्तर है "यह उतना व्यक्तिपरक नहीं है जितना आपने सोचा था, लेकिन सटीक सीमाएं काफी हद तक एक नियम-आधारित अंगूठे का निर्णय हैं ... और experiemental सबूत है कि यह काफी अच्छा था। "


3

अधिकतम उच्च पूर्णांक मान जिसे कैश किया जा सकता है उसे सिस्टम प्रॉपर्टी java.lang.Integer.IntegerCache.high( -XX:AutoBoxCacheMax) के माध्यम से कॉन्फ़िगर किया जा सकता है । एक सरणी का उपयोग करके कैश को कार्यान्वित किया जाता है।

    private static class IntegerCache {
    static final int high;
    static final Integer cache[];

    static {
        final int low = -128;

        // high value may be configured by property
        int h = 127;
        if (integerCacheHighPropValue != null) {
            // Use Long.decode here to avoid invoking methods that
            // require Integer's autoboxing cache to be initialized
            int i = Long.decode(integerCacheHighPropValue).intValue();
            i = Math.max(i, 127);
            // Maximum array size is Integer.MAX_VALUE
            h = Math.min(i, Integer.MAX_VALUE - -low);
        }
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);
    }

    private IntegerCache() {}
}

0

जब आप इंटेगर वर्ग के साथ मुठभेड़ करते हैं और हमेशा सीमा -128 से 127 के भीतर बॉक्सिंग करते हैं तो यह हमेशा बेहतर होता है कि नीचे दिए गए इंटर्गर ऑब्जेक्ट को इंट वैल्यू में बदलें।

<Your Integer Object>.intValue()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.