2012-09-16 9 views
5

इस क्वेरी का उद्देश्य जावा और सी ++ के एक पहलू की तुलना करना है, जिसे "नए" ऑपरेटर के साथ करना है।चूंकि सभी ऑब्जेक्ट जावा में "नया" के साथ बनाए जाते हैं, इसका मतलब यह है कि वे सभी हीप पर बनाए गए हैं?

अब, मुझे पता है कि सी ++ में वस्तुओं को बनाने के दो तरीके हैं; "नए" ऑपरेटर के साथ या उसके बिना। उस ऑपरेटर की अनुपस्थिति में, ढेर क्षेत्र में अंतरिक्ष आवंटित नहीं किया जाता है, जबकि, इसकी उपस्थिति में, ढेर क्षेत्र में अंतरिक्ष आवंटित किया जाता है।

जावा के बारे में क्या? मैंने देखा है कि "नया" ऑपरेटर प्रत्येक ऑब्जेक्ट बनाने के लिए उपयोग किया जाता है। यहां तक ​​कि "नए" ऑपरेटर के साथ सरणी भी बनाई गई हैं। क्या इसका मतलब यह है कि जावा में वस्तुओं के अस्तित्व के लिए केवल एक ही जगह है - यानी, ढेर क्षेत्र?

धन्यवाद।

+3

सामान्यतः, एक कीवर्ड के लिए एक ही नाम समानता का संकेत नहीं देता है - कभी-कभी बस होता है। – Linuxios

+0

क्या मुझे जवाब चुनना है? मुझे नहीं पता था। – softwarelover

+0

(मैंने सी ++ टैग हटा दिया और शीर्षक को और अधिक परिष्कृत किया, भले ही लंबा हो। अब, यदि प्रश्न सी # के बारे में था - जो अभी भी वैल्यू प्रकारों के लिए 'नया' का उपयोग करता है जो "आवंटन ढेर" से बच सकता है - उत्तर होंगे * अलग * के रूप में सी # जावा नहीं है जैसे जावा सी ++ नहीं है।) –

उत्तर

6

हां, नया ऑपरेटर हमेशा ढेर पर ऑब्जेक्ट के लिए स्मृति आवंटित करता है। सी ++ के विपरीत, जावा में ऑब्जेक्ट्स को स्टैक पर नहीं बनाया जा सकता है।

+2

ढेर की धारणा कार्यान्वयन-विशिष्ट है, वर्चुअल मशीन विशिष्टता के लिए जानबूझकर स्टोरेज विकल्पों को प्रतिबंधित नहीं करता है। – oldrinb

+2

+1 इसके बजाय "सी ++ के विपरीत, जावा में कहने का कोई तरीका नहीं है कि आप स्टैक पर आवंटित ऑब्जेक्ट चाहते हैं" –

+0

भविष्य में मुबारक टिप्पणी। ;) –

4

स्थानीय आदिम प्रकार, और स्थानीय संदर्भ ऑब्जेक्ट प्रकारों के लिए, दोनों "स्टैक" मेमोरी लेते हैं, जैसा कि वे दोनों विधियों के पैरामीटर के रूप में पारित करते हैं।

सभी ऑब्जेक्ट्स स्वयं "ढेर" के बराबर मौजूद हैं।

+1

@softwarelover जावा ऑब्जेक्ट्स का भंडारण जानबूझकर वर्चुअल मशीन विशिष्टता द्वारा निर्दिष्ट नहीं किया गया है; यह मेरे वीएम जैसे हॉटस्पॉट का लाभ उठाता है जो वस्तुओं के लिए स्टैक आवंटन का लाभ लेने के लिए बचने के विश्लेषण का उपयोग करता है :-) – oldrinb

+1

वह किसी भी ब्लॉक (उदा।, फ़ंक्शन बॉडी) में कुछ स्थानीय चर मौजूद है। चाहे वे प्राइमेटिव या आवंटित ऑब्जेक्ट्स हों, दोनों के पास स्टैक पर कुछ उपस्थिति है: प्राइमेटिव्स स्टैक पर पूरी तरह से हैं (उदाहरण के लिए, 4 बाइट 'int' स्टैक पर 4 बाइट्स है)। आवंटित वस्तुओं को आसानी से ढेर पर पॉइंटर्स के रूप में सोचा जा सकता है; वे एक सूचक की तरह ढेर पर जगह लेते हैं, जिसका प्रयोग स्मृति में इंगित वास्तविक वस्तु को संदर्भित करने के लिए किया जाता है ('नया' का उपयोग करके बनाया गया)। जैसा कि @oldrinb बताता है, यह ठीक नहीं हो सकता है, लेकिन यह प्रभावी ढंग से हो रहा है। – pickypg

+0

धन्यवाद pickypg, अब मैं समझता हूं कि Alnitak क्या कहा। मैंने ध्यान से नहीं पढ़ा .. – softwarelover

2

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

वास्तव में, जावा में पहली श्रेणी जावा ऑब्जेक्ट्स बनाई जा सकती हैं, जो कि new कीवर्ड का उपयोग करने में शामिल नहीं हैं।

  • { ... } सरणी प्रारंभकर्ता वाक्य रचना new कीवर्ड के बिना एक सरणी घोषणा में इस्तेमाल किया जा सकता।

  • ए स्ट्रिंग अक्षर में स्ट्रिंग ऑब्जेक्ट (कक्षा लोड समय पर) का निर्माण शामिल है।

  • मुक्केबाजी रूपांतरण (आमतौर पर) एक स्पष्ट new या विधि कॉल के बिना एक नया रैपर ऑब्जेक्ट बना देगा।

  • चिंतनशील newInstance और इसी तरह के तरीकों एक स्पष्ट new बिना वस्तुओं को बनाने के।

  • हुड के तहत, जावा धारावाहिकरण के कार्यान्वयन Unsafe कक्षा में किसी विशेष घोषित कन्स्ट्रक्टर को निष्पादित किए बिना ऑब्जेक्ट बनाने के लिए एक विशेष विधि का उपयोग करता है।

  • आप जेएनआई/जेएनए एपिस का उपयोग कर देशी कोड में जावा ऑब्जेक्ट्स भी बना सकते हैं।

(वहाँ एक मजबूत तर्क यह है कि पिछले दो "नहीं जावा" हैं, लेकिन वे वैसे भी उल्लेख के लायक हैं। और स्ट्रिंग शाब्दिक और ऑटो मुक्केबाजी मामलों जावा कोड हुड के नीचे new का उपयोग करता है को शामिल करना है।)


1 - एक से अधिक ढेर, नहीं हो सकता है, हालांकि इस आवेदन के लिए पारदर्शी है।

2 - नवीनतम हॉटस्पॉट जेवीएम में एक प्रयोगात्मक "बचने का विश्लेषण" सुविधा है जो यह निर्धारित करती है कि क्या वे संदर्भित किए गए संदर्भ से "भागने" वस्तुएं हैं या नहीं। ऑब्जेक्ट जो बचते नहीं हैं उन्हें स्टैक पर सुरक्षित रूप से आवंटित किया जा सकता है। एक बार फिर, यह अनुकूलन आवेदन के लिए पारदर्शी है।

+0

हालांकि यह अच्छी जानकारी है, यह "ढेर पर/ढेर पर" के मूल प्रश्न का उत्तर नहीं देती है। "ध्यान रखें कि ऑब्जेक्ट हमेशा ढेर पर बनाए जाते हैं" और यह सबसे अच्छा जवाब होगा। – EdC

+0

@ एडीसी: आपके साथ सहमत! – softwarelover

0

जावा में, सभी ऑब्जेक्ट्स गतिशील रूप से हीप पर आवंटित किए जाते हैं। यह सी ++ से अलग है जहां वस्तुओं को या तो ढेर या ढेर पर स्मृति आवंटित किया जा सकता है। सी ++ में, जब हम new() का उपयोग करके अकसर आवंटित करते हैं, तो आधार को हेप पर आवंटित किया जाता है, अन्यथा वैश्विक या स्थैतिक नहीं होने पर स्टैक पर।

जावा में, जब हम केवल कक्षा प्रकार के चर को घोषित करते हैं, केवल एक संदर्भ बनाया जाता है (वस्तु के लिए स्मृति आवंटित नहीं की जाती है)। किसी ऑब्जेक्ट को स्मृति आवंटित करने के लिए, हमें नए() का उपयोग करना होगा। तो ऑब्जेक्ट हमेशा ढेर पर स्मृति आवंटित किया जाता है।

उदाहरण 1: संकलन त्रुटि दें।

class Test { 
    void show() { 
     System.out.println("Test::show() called"); 
    } 
}  
public class Main { 
    public static void main(String[] args) { 
     Test t; 
     t.show(); // Error here because t is not initialed 
    } 

उदाहरण 2: आवंटन स्मृति new() का उपयोग कर कार्यक्रम काम से ऊपर बना देता है।

class Test { 
    void show() { 
     System.out.println("Test::show() called"); 
    } 
}  
public class Main { 
    public static void main(String[] args) { 
     Test t = new Test(); //all objects are dynamically allocated 
     t.show(); // No error 
    } 
} 
संबंधित मुद्दे