जावा: गैर सरणी तत्वों के साथ आरंभिक सरणी


130

जेएलएस के अनुसार, एक intसरणी को आरंभीकरण के ठीक बाद शून्य से भरना चाहिए। हालांकि, मैं एक ऐसी स्थिति से सामना कर रहा हूं जहां यह नहीं है। ऐसा व्यवहार पहले JDK 7u4 में होता है और बाद के सभी अपडेट में भी होता है (मैं 64-बिट कार्यान्वयन का उपयोग करता हूं)। निम्नलिखित कोड अपवाद फेंकता है:

public static void main(String[] args) {
        int[] a;
        int n = 0;
        for (int i = 0; i < 100000000; ++i) {
            a = new int[10];
            for (int f : a)
                if (f != 0)
                  throw new RuntimeException("Array just after allocation: "+ Arrays.toString(a));
            Arrays.fill(a, 0);
            for (int j = 0; j < a.length; ++j)
                a[j] = (n - j)*i;
            for (int f : a)
                n += f;
        }
        System.out.println(n);
    }

JVM कोड ब्लॉक का संकलन करने और -Xintझंडे के साथ उत्पन्न नहीं होने के बाद अपवाद होता है । इसके अतिरिक्त, Arrays.fill(...)कथन (इस कोड में अन्य सभी कथन) आवश्यक है, और अनुपस्थित होने पर अपवाद नहीं होता है। यह स्पष्ट है कि यह संभव बग कुछ JVM ऑप्टिमाइज़ेशन से घिरा हुआ है। इस तरह के व्यवहार के कारण के लिए कोई विचार?

अद्यतन:
मैं हॉटस्पॉट 64-बिट सर्वर VM, जावा संस्करण 1.7.0_04 से 1.7.0_10 पर Gentoo लिनक्स, डेबियन लिनक्स (दोनों कर्नेल 3.0 संस्करण) और MacOS शेर पर इस व्यवहार को देखता हूं। यह त्रुटि हमेशा ऊपर दिए गए कोड के साथ पुन: प्रस्तुत की जा सकती है। मैंने 32-बिट JDK के साथ या विंडोज पर इस समस्या का परीक्षण नहीं किया। मैंने पहले ही Oracle (बग आईडी 7196857) को एक बग रिपोर्ट भेज दी थी और यह कुछ दिनों में सार्वजनिक Oracle बग डेटाबेस में दिखाई देगा।

अद्यतन:
Oracle ने इस बग को अपने सार्वजनिक बग डेटाबेस में प्रकाशित किया: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7196857


15
मैं कार्यान्वयन में बग कहता हूँ अगर यह कल्पना का पालन नहीं कर रहा है
पेटेश

12
चूंकि आपके पास एक अच्छी तरह से परिभाषित उदाहरण है जो समस्या को मज़बूती से पुन: उत्पन्न करता है (कम से कम कुछ प्लेटफार्मों पर), क्या आपने बग दर्ज करने पर विचार किया है ?
जोकिम सॉर

4
हाँ, आपको सबसे निश्चित रूप से एक बग रिपोर्ट दर्ज करनी चाहिए। यह एक बहुत ही गंभीर बग है!
हॉट लिप्स

7
हां, मैंने पहले ही ओरेकल (बग आईडी 7196857) को एक बग रिपोर्ट भेज दी है और यह कुछ दिनों में सार्वजनिक ओरेकल बग डेटाबेस में दिखाई देगा।
स्टैनिस्लाव पॉस्लेव्स्की

6
मैंने इसे विंडोज 7 पर जावा 7 अपडेट 7 64-बिट के साथ आज़माया और इसमें कोई समस्या नहीं थी।
पीटर लॉरी

जवाबों:


42

यहाँ हम JIT- कंपाइलर में एक बग के साथ सामना कर रहे हैं। कंपाइलर निर्धारित करता है कि आबंटित ऐरे को आबंटन के बाद भरा जाता है Arrays.fill(...), लेकिन आबंटन और भरण के बीच के उपयोग की जाँच दोषपूर्ण है। इसलिए, कंपाइलर एक अवैध अनुकूलन करता है - यह आवंटित सरणी के शून्यकरण को पूरा करता है।

यह बग ओरेकल बग ट्रैकर ( बग आईडी 7196857 ) में रखा गया है । दुर्भाग्य से, मैंने निम्नलिखित बिंदुओं के बारे में ओरेकल के किसी स्पष्टीकरण का इंतजार नहीं किया। जैसा कि मैं देखता हूं, यह बग ओएस-विशिष्ट है: यह 64-बिट लिनक्स और मैक पर बिल्कुल प्रतिलिपि प्रस्तुत करने योग्य है, लेकिन, जैसा कि मैं टिप्पणियों से देखता हूं, यह नियमित रूप से विंडोज (जेडडीके के समान संस्करणों के लिए) पर पुन: पेश नहीं करता है। इसके अतिरिक्त यह जानना अच्छा होगा कि इस बग को कब ठीक किया जाएगा।

इस समय केवल सलाह है: JDK1.7.0_04 का उपयोग न करें या बाद में यदि आप नए चेक के लिए JLS पर निर्भर हैं।

5 अक्टूबर को अपडेट करें:

04 अक्टूबर, 2012 को जारी JDK 7u10 (शुरुआती पहुंच) के नए बिल्ड 10 में, यह बग कम से कम लिनक्स ओएस के लिए तय किया गया था (मैंने अन्य के लिए परीक्षण नहीं किया था)। @Makoto का धन्यवाद, जिन्होंने पाया कि यह बग अब Oracle बग डेटाबेस में सार्वजनिक पहुंच के लिए उपलब्ध नहीं है। दुर्भाग्य से, मुझे नहीं पता कि किन कारणों से ओरेकल ने इसे सार्वजनिक पहुंच से हटा दिया, लेकिन यह Google कैश में उपलब्ध है । इसके अलावा, इस बग Redhat का ध्यान आकर्षित किया: CVE पहचानकर्ता CVE-2012-4420 ( बगजिला ) और CVE-2012-4416 ( बगजिला ) इस दोष को सौंपा गया।


2
बग आईडी अब अमान्य है - क्या आप इस पर गौर कर सकते हैं?
माकोटो

1
@ माकोतो मैं भ्रमित हूं, क्योंकि यह बग कल बग डेटाबेस में था। मुझे पता नहीं है कि ओरेकल ने इस बग को सार्वजनिक पहुंच से हटा दिया था। लेकिन गूगल याद webcache.googleusercontent.com/... साथ ही इस बग भी है क्योंकि यह एक CVE को जन्म दे सकता, RedHat बग डेटाबेस में रखा गया था bugzilla.redhat.com/show_bug.cgi?id=856124
स्टानिस्लाव Poslavsky

0

मैंने आपके कोड में कुछ बदलाव किया है। यह इंटेगर के अतिप्रवाह की समस्या नहीं है। कोड देखें, यह रनटाइम पर एक अपवाद फेंकता है

    int[] a;
    int n = 0;
    for (int i = 0; i < 100000000; ++i) {
        a = new int[10];
        for (int f : a) {
            if (f != 0) {
                throw new RuntimeException("Array just after allocation: " + Arrays.toString(a));
            }
        }
        for (int ii = 0, len = a.length; ii < len; ii++)
            a[ii] = 0;
        for (int j = 0; j < a.length; ++j)
            a[j] = Integer.MAX_VALUE - 1;
        for (int j = 0; j < a.length; ++j)
            n++;
    }

विंडोज 7 64 बिट। Jdk 64 बिट 1.7.0_07
रॉबर्टो मेरिगेटी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.