2010-01-20 6 views
70

मेरे पास इस तरह की एक सरणी घोषणा है:क्या ढेर या ढेर में संग्रहीत प्राइमेटिव की जावा सरणी है?

int a[]; 

यहां a आदिम int प्रकार की एक सरणी है। यह सरणी कहां संग्रहीत है? क्या यह ढेर या ढेर पर संग्रहीत है? यह एक primitve प्रकार int है, सभी आदिम प्रकार ढेर पर संग्रहीत नहीं हैं।

+35

यह एक सरणी नहीं है। यह एक सरणी का संदर्भ है। संदर्भ स्वयं ही ढेर पर संग्रहीत किया जा सकता है यदि यह किसी वर्ग या ऑब्जेक्ट का सदस्य है, या स्टैक पर यदि यह किसी विधि में स्थानीय चर है। और यदि वे वर्ग या वस्तु के सदस्य हैं तो आदिम प्रकार ढेर पर संग्रहीत किए जा सकते हैं। – UncleO

उत्तर

32

यह ढेर

पर संग्रहीत किया जाएगा क्योंकि सरणी जावा में एक वस्तु है।

संपादित:। यदि आपके पास संकलक करने के लिए कहा, "एक सरणी उद्देश्य यह है कि चार ints का आयोजन करेगा, और testScores नामित संदर्भ चर के लिए असाइन करें बनाएं रूप में इस कोड की

int [] testScores; 
testScores = new int[4]; 

Think इसके अलावा , आगे बढ़ें और प्रत्येक int तत्व शून्य पर सेट करें। धन्यवाद। "

+2

और टेस्टस्कोर्स नामक संदर्भ चर (ढेर पर सरणी को इंगित करना) ढेर पर होगा। – Zaki

+8

कोड केवल "धन्यवाद" कहता है यदि आप कंपाइलर को '-g' विकल्प प्रदान करते हैं। अन्यथा इसे अनुकूलित किया जाएगा। – mob

+0

@mob आप एक धारणा बना रहे हैं कि यह एकमात्र कोड है। यह मानना ​​शायद बेहतर है कि ये दो रेखाएं एक बड़े कार्यक्रम का हिस्सा हैं जो वास्तव में सरणी का उपयोग करती है। –

2

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

http://java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html

18

यह आदिम प्रकार जो अपने आप में आदिम नहीं है की एक सरणी है। अंगूठे का एक अच्छा नियम तब होता है जब नया कीवर्ड शामिल होता है तो परिणाम ढेर पर होगा।

132

जैसा कि गुरुकुल्की ने कहा, यह ढेर पर संग्रहीत है। हालांकि, आपकी पोस्ट ने कुछ गलत इरादे वाले व्यक्ति के कारण शायद गलतफहमी का सुझाव दिया कि मिथक का प्रचार "प्राइमेटिव्स हमेशा स्टैक पर रहते हैं"। यह असत्य है। स्थानीय चर ढेर पर उनके मूल्यों है, लेकिन सभी आदिम चर स्थानीय रहे हैं ...

उदाहरण के लिए, इस पर विचार करें:

public class Foo 
{ 
    int value; 
} 
... 

public void someOtherMethod() 
{ 
    Foo f = new Foo(); 
    ... 
} 

अब, जहां f.value रहते है? मिथक सुझाव देगा कि यह ढेर पर है - लेकिन वास्तव में यह नए Foo ऑब्जेक्ट का हिस्सा है, और ढेर पर रहता है। (ध्यान दें कि f का मान स्वयं एक संदर्भ है, और ढेर पर रहता है।)

वहां से, यह सरणी के लिए एक आसान कदम है। तुम बस चर का एक बहुत होने के रूप में एक सरणी के बारे में सोच सकते हैं - तो new int[3] इस फार्म के एक वर्ग के होने की तरह एक सा है:

public class ArrayInt3 
{ 
    public readonly int length = 3; 
    public int value0; 
    public int value1; 
    public int value2; 
} 

वास्तव में, यह इस तुलना में अधिक जटिल है। ढेर/ढेर भेद अधिकतर कार्यान्वयन विस्तार है - मेरा मानना ​​है कि कुछ जेवीएम, संभवतः प्रयोगात्मक वाले, यह बता सकते हैं कि कोई ऑब्जेक्ट किसी विधि से "बच निकला" नहीं है, और पूरे ऑब्जेक्ट को ढेर पर आवंटित कर सकता है। हालांकि, यदि आप देखभाल करना चुनते हैं, तो यह अवधारणात्मक रूप से ढेर पर है।

+1

जावा में "बचने के विश्लेषण" के बारे में: http://blog.juma.me.uk/2008/12/17/objects-with-no-allocation-overhead/ यह कहता है कि यह प्रारंभिक पहुंच के बाद से मौजूद है जेडीके 6 अपडेट 14 की रिलीज, और जेडीके 6 अपडेट 23 के बाद डिफ़ॉल्ट रूप से सक्षम है। –

+0

यदि सरणी सार्वजनिक स्थिर अंतिम है तो क्या यह कुछ भी बदलता है? क्या यह तब निरंतर पूल का हिस्सा नहीं होना चाहिए? – Malachiasz

+0

@ मालाचियाज़: नहीं। एक सरणी कभी स्थिर नहीं है। –

14

मैं बस इस विषय पर चलाए गए कुछ परीक्षण साझा करना चाहता था।

आकार की सरणी 10 लाख

public static void main(String[] args) { 
    memInfo(); 
    double a[] = new double[10000000]; 
    memInfo(); 
} 

आउटपुट:

------------------------ 
max mem = 130.0 MB 
total mem = 85.0 MB 
free mem = 83.6 MB 
used mem = 1.4 MB 
------------------------ 
------------------------ 
max mem = 130.0 MB 
total mem = 130.0 MB 
free mem = 48.9 MB 
used mem = 81.1 MB 
------------------------ 

जैसा कि आप देख के रूप में इस्तेमाल ढेर आकार ~ 80 एमबी है, जो 10 मी * sizeof है बढ़ जाती है (डबल)।

लेकिन अगर हम डबल

public static void main(String[] args) { 
    memInfo(); 
    Double a[] = new Double[10000000]; 
    memInfo(); 
} 

आउटपुट की डबल बजाय का उपयोग किया है 40MB दिखाएगा। हमारे पास केवल डबल संदर्भ हैं, वे प्रारंभ नहीं किए गए हैं।

डबल

public static void main(String[] args) { 
    memInfo(); 
    Double a[] = new Double[10000000];  
    Double qq = 3.1d; 
    for (int i = 0; i < a.length; i++) { 
     a[i] = qq; 
    } 
    memInfo(); 
} 

फिर भी 40MB के साथ इसे भरने। क्योंकि वे सभी एक ही डबल ऑब्जेक्ट को इंगित करते हैं।

डबल बजाय

public static void main(String[] args) { 
    memInfo(); 
    Double a[] = new Double[10000000]; 
    Double qq = 3.1d; 
    for (int i = 0; i < a.length; i++) { 
     a[i] = qq.doubleValue(); 
    } 
    memInfo(); 
} 

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 

साथ आरंभ किया जा रहा लाइन

a[i] = qq.doubleValue(); 

a[i] = Double.valueOf(qq.doubleValue()); 

जो

a[i] = new Double(qq.doubleValue()); 
0 के बराबर है के बराबर है

चूंकि हम हर बार नई डबल ऑब्जेक्ट्स बनाते हैं, हम ढेर को उड़ाते हैं। यह दिखाता है कि डबल क्लास के अंदर मान ढेर में संग्रहीत हैं।

संबंधित मुद्दे