मेरे पास इस तरह की एक घोषणा है:
int a[];
यहाँ a
आदिम int
प्रकार की एक सरणी है । यह सरणी कहाँ संग्रहीत है? क्या यह ढेर या ढेर पर संग्रहीत है? यह एक int
आदिम प्रकार है, सभी आदिम प्रकार ढेर पर संग्रहीत नहीं हैं।
मेरे पास इस तरह की एक घोषणा है:
int a[];
यहाँ a
आदिम int
प्रकार की एक सरणी है । यह सरणी कहाँ संग्रहीत है? क्या यह ढेर या ढेर पर संग्रहीत है? यह एक int
आदिम प्रकार है, सभी आदिम प्रकार ढेर पर संग्रहीत नहीं हैं।
जवाबों:
जैसा कि गुरुकुलकी ने कहा, यह ढेर पर जमा है। हालाँकि, आपकी पोस्ट ने किसी गलत इरादे वाले व्यक्ति द्वारा मिथक का प्रचार करने के कारण शायद गलतफहमी का सुझाव दिया कि "आदिम हमेशा ढेर पर रहते हैं"। यह असत्य है। स्थानीय चर के ढेर पर उनके मूल्य हैं, लेकिन सभी आदिम चर स्थानीय नहीं हैं ...
उदाहरण के लिए, इस पर विचार करें:
public class Foo
{
int value;
}
...
public void someOtherMethod()
{
Foo f = new Foo();
...
}
अब, कहाँ f.value
रहता है? मिथक यह स्टैक पर सुझाएगा - लेकिन वास्तव में यह नई Foo
वस्तु का हिस्सा है , और ढेर 1 पर रहता है । (ध्यान दें कि f
स्वयं का मूल्य एक संदर्भ है, और स्टैक पर रहता है।)
वहाँ से, यह सरणियों के लिए एक आसान कदम है। आप एक सरणी के बारे में सोच सकते हैं जैसे कि बस बहुत सारे चर होते हैं - इसलिए new int[3]
इस फॉर्म का एक वर्ग होने जैसा है:
public class ArrayInt3
{
public readonly int length = 3;
public int value0;
public int value1;
public int value2;
}
1 वास्तव में, यह इससे अधिक जटिल है। स्टैक / हीप डिस्टिंक्शन ज्यादातर एक कार्यान्वयन विवरण है - मेरा मानना है कि कुछ JVM, संभवतः प्रयोगात्मक वाले, बता सकते हैं कि कोई वस्तु कभी किसी विधि से "पलायन" नहीं करती है, और स्टैक पर पूरी वस्तु को आवंटित कर सकती है। हालाँकि, यह वैचारिक रूप से ढेर पर है, अगर आप देखभाल करना चुनते हैं।
String
एक द्वारा समर्थित है char[]
। मेरा मानना है कि शाब्दिक तार सार्वजनिक स्थिर पूल में संग्रहीत किए जाते हैं; जीसी ऑप्टिमाइज़ेशन के लिए, इसका अर्थ यह होगा कि बैकिंग सरणियों को इसी तरह संग्रहित किया जाना चाहिए (अन्यथा निरंतर जीसी को किसी भी जीसी चक्र के दौरान स्कैन करना होगा जहां बैकिंग सरणी अन्यथा संग्रह के लिए योग्य होगी)।
यह ढेर पर संग्रहीत किया जाएगा
क्योंकि सरणी जावा में एक वस्तु है।
संपादित करें : यदि आपके पास है
int [] testScores;
testScores = new int[4];
इस कोड को कंपाइलर से यह कहते हुए सोचें, "एक एरे ऑब्जेक्ट बनाएं, जो चार इन्टल्स रखेगा, और इसे नामांकित संदर्भ वेरिएबल में असाइन करेगा testScores
। इसके अलावा, आगे बढ़ें और प्रत्येक int
एलिमेंट को शून्य पर सेट करें । धन्यवाद।"
-g
संकलक के लिए विकल्प की आपूर्ति करते हैं तो कोड केवल "धन्यवाद" कहता है । अन्यथा इसे दूर किया जाएगा।
यह आदिम प्रकार की एक सरणी है जो अपने आप में आदिम नहीं है। अंगूठे का एक अच्छा नियम है जब नया कीवर्ड शामिल होता है तो परिणाम ढेर पर होगा।
मैं सिर्फ इस विषय पर कुछ परीक्षण साझा करना चाहता था।
आकार की संख्या 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 मीटर * आकार का (डबल) है।
लेकिन अगर हमारे पास डबल के बजाय डबल का उपयोग होता है
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();
}
फिर भी 40 एमबी। क्योंकि वे सभी एक ही डबल ऑब्जेक्ट की ओर इशारा करते हैं।
इसके बजाय डबल के साथ प्रारंभ करना
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());
चूंकि हम हर बार नई डबल ऑब्जेक्ट बनाते हैं, हम ढेर को उड़ा देते हैं। इससे पता चलता है कि डबल क्लास के अंदर मान ढेर में जमा हैं।
जावा प्रोग्रामिंग भाषा में एरेज़ ऑब्जेक्ट हैं, गतिशील रूप से बनाए जाते हैं, और इन्हें ऑब्जेक्ट के वेरिएबल्स को सौंपा जा सकता है।
http://java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html