2014-09-04 6 views
13

गोलांग में, ऐसा लगता है कि कोई रचनाकार नहीं हैं, लेकिन यह सुझाव दिया जाता है कि आप एक फ़ंक्शन का उपयोग करके एक स्ट्रक्चर प्रकार का ऑब्जेक्ट आवंटित करते हैं, जिसे आम तौर पर "नया" + टाइपनाम द्वारा नामित किया जाता है, उदाहरण के लिएसीओ ++/सी

func NewRect(x,y, width, height float) *Rect { 
    return &Rect(x,y,width, height) 
} 

हालांकि, मुझे गो के मेमोरी लेआउट के बारे में निश्चित नहीं है। सी/सी ++ में, इस प्रकार का कोड का मतलब है कि आप एक पॉइंटर लौटाते हैं, जो अस्थायी ऑब्जेक्ट को इंगित करता है क्योंकि चर को स्टैक पर आवंटित किया जाता है, और फ़ंक्शन रिटर्न के बाद चर कुछ ट्रैश हो सकता है। गोलांग में, क्या मुझे ऐसी चीज चिंता करने की ज़रूरत है? क्योंकि ऐसा लगता है कि कोई मानक दिखाता है कि ढेर पर किस तरह का डेटा आवंटित किया जाएगा, इस प्रकार किस प्रकार का डेटा आवंटित किया जाएगा।

जावा में, ऐसा लगता है कि मूल प्रकार जैसे int, float को स्टैक पर आवंटित किया जाएगा, ऑब्जेक्ट से व्युत्पन्न अन्य ऑब्जेक्ट ढेर पर आवंटित किया जाएगा। गोलांग में, क्या इस बारे में एक विशिष्ट बात है?

+5

इसे ढेर पर आवंटित किया जाएगा। गो कंपाइलर यह पता लगा सकता है कि जब कोई ऑब्जेक्ट स्टैक के बाहर रहता है, और स्वचालित रूप से इसे ढेर पर आवंटित करता है। ऑप्टिमाइज़ेशन फैसले देखने के लिए आप 'go build -gcflags' -m'' के साथ संकलित करते हैं, तो आप इसे देख सकते हैं। – siritinga

+2

@python: आपका अंतर्ज्ञान सही था कि आपको इसके बारे में चिंता करने की ज़रूरत नहीं है। व्यवहार में यह सच है कि इसे ढेर पर आवंटित किया जाएगा, लेकिन गो का मेमोरी मॉडल बहुत आसान है, और आपको वास्तव में ढेर और ढेर के बारे में सोचना नहीं है। आप चर के बारे में सोच सकते हैं। यदि आप किसी चीज़ का पता लेते हैं, तो गो गारंटी देगा कि वह पता तब तक मान्य रहता है जब तक आपके पास कोई पॉइंटर न हो। यह प्रोग्रामर के रूप में आपके लिए कोई फर्क नहीं पड़ता कि यह कैसे होता है। (हालांकि, जाहिर है, यह सोचने के लिए दिलचस्प हो सकता है कि यह कैसे कार्यान्वित किया गया है, और वहां कुछ अच्छी चीजें भी चल रही हैं) – joshlf

+0

आपके सभी लोगों के लिए धन्यवाद – python

उत्तर

26

Composite Literal section का उल्लेख है:

एक समग्र शाब्दिक का पता (§Address ऑपरेटरों) उत्पन्न की शाब्दिक मूल्य का एक उदाहरण के लिए एक अनूठा सूचक ले रहा है।

इसका मतलब है कि New फ़ंक्शन द्वारा लौटा गया सूचक एक वैध (स्टैक पर आवंटित) होगा।
Calls:

एक समारोह कॉल में, समारोह मूल्य और तर्क सामान्य क्रम में मूल्यांकन कर रहे हैं।
उनका मूल्यांकन होने के बाद, कॉल के पैरामीटर फ़ंक्शन के मान द्वारा पारित किए जाते हैं और कॉल किए गए फ़ंक्शन निष्पादन शुरू होते हैं।
फ़ंक्शन के रिटर्न पैरामीटर मान द्वारा वापस कॉलिंग फ़ंक्शन पर पास किए जाते हैं जब फ़ंक्शन देता है।

आप अधिक in this answer और this thread देख सकते हैं।

"Stack vs heap allocation of structs in Go, and how they relate to garbage collection" में उल्लेख किया है:

यह ध्यान देने योग्य है कि शब्द "ढेर" और "ढेर" भाषा कल्पना में कहीं भी दिखाई नहीं देते हैं लायक है।


blog post "Escape Analysis in Go" विवरण क्या होता है, mentioning the FAQ:

जब संभव हो, जाओ compilers चर कि समारोह के ढेर फ्रेम में एक समारोह के लिए स्थानीय कर रहे हैं आवंटित करेगा।
हालांकि, यदि संकलक यह साबित नहीं कर सकता कि फ़ंक्शन रिटर्न के बाद परिवर्तनीय संदर्भित नहीं किया गया है, तो संकलक को सूचकांक को लटकने से बचने के लिए कचरे से एकत्रित ढेर पर चर आवंटित करना होगा।
इसके अलावा, यदि कोई स्थानीय चर बहुत बड़ा है, तो यह ढेर के बजाय ढेर पर इसे स्टोर करने के लिए और अधिक समझ सकता है।

ब्लॉग पोस्ट को जोड़ता है:

कोड "विश्लेषण पलायन" करता है कि src/cmd/gc/esc.c में रहती है।
संकल्पनात्मक रूप से, यह निर्धारित करने का प्रयास करता है कि कोई स्थानीय चर वर्तमान दायरे से बच निकलता है; केवल दो मामले जहां ऐसा होता है जब एक चर का पता लौटाया जाता है, और जब उसका पता बाहरी चरम पर एक चर को आवंटित किया जाता है।
यदि कोई चर निकलता है, तो उसे ढेर पर आवंटित किया जाना चाहिए; अन्यथा, इसे ढेर पर रखना सुरक्षित है।

दिलचस्प बात यह है कि यह new(T) आवंटन पर भी लागू होता है।
यदि वे भाग नहीं जाते हैं, तो वे ढेर पर आवंटित किए जाएंगे। यहाँ मामलों को स्पष्ट करने के लिए एक उदाहरण है:

var intPointerGlobal *int = nil 

func Foo() *int { 
    anInt0 := 0 
    anInt1 := new(int) 

    anInt2 := 42 
    intPointerGlobal = &anInt2 

    anInt3 := 5 

    return &anInt3 
} 

ऊपर, anInt0 और anInt1 से बच नहीं रहे हैं इसलिए उनके ढेर पर आवंटित कर रहे हैं;
anInt2 और anInt3 भागने, और ढेर पर आवंटित किए जाते हैं।


भी देखें "Five things that make Go fast":

सी, जो बलों को चुनने के लिए यदि एक मूल्य के ढेर पर संग्रहीत किया जाएगा, malloc के माध्यम से, या ढेरों पर विपरीत, यह घोषणा करके फ़ंक्शन के दायरे के अंदर, एस्केप विश्लेषण नामक एक अनुकूलन लागू करता है।

गो के अनुकूलन हमेशा डिफ़ॉल्ट रूप से सक्षम होते हैं।
आप संकलक के बचने के विश्लेषण और -gcflags=-m स्विच के साथ निर्णयों को रेखांकित कर सकते हैं।

क्योंकि संकलन समय पर भागने का विश्लेषण किया जाता है, रन नहीं समय, स्टैक आवंटन हमेशा आवंटन ढेर से तेज़ होगा, इससे कोई फर्क नहीं पड़ता कि आपका कचरा कलेक्टर कितना कुशल है।

+1

भले ही spec इसका उल्लेख नहीं करता है, संकलक इसके बचने के विश्लेषण में करता है: './test।जाओ: 11: नया (int) ढेर से निकलता है – siritinga

+0

@siritinga वास्तव में। मैंने http://stackoverflow.com/questions/13715237/return-pointer-to-local-struct#comment23436456_13715281 – VonC

+0

से आने वाले भागने विश्लेषण पर अधिक जानकारी के साथ उत्तर संपादित किया है, यह सिर्फ एक टिप्पणी थी। अंत में ढेर/ढेर शर्तों का उपयोग करना टालना इतना आसान नहीं है :) – siritinga

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