इनमें से अधिकतर सीपीआई दस्तावेज के Memory Management अध्याय में उत्तर दिया गया है।
कुछ दस्तावेज जो आप पूछ रहे हैं उससे योनर है। अधिक जानकारी के लिए, आपको स्रोत कोड पर जाना होगा। और जब तक आप एक विशिष्ट संस्करण नहीं चुनते हैं तब तक कोई भी ऐसा करने के लिए तैयार नहीं होगा। (कम से कम 2.7.5, प्री-2.7.6, 3.3.2, प्री-3.3.3, और प्री-3.4 अलग-अलग लोगों के लिए दिलचस्प होगा।)
obmalloc.c
फ़ाइल का स्रोत एक अच्छी प्रारंभिक जगह है
Object-specific allocators
_____ ______ ______ ________
[ int ] [ dict ] [ list ] ... [ string ] Python core |
+3 | <----- Object-specific memory -----> | <-- Non-object memory --> |
_______________________________ | |
[ Python`s object allocator ] | |
+2 | ####### Object memory ####### | <------ Internal buffers ------> |
______________________________________________________________ |
[ Python`s raw memory allocator (PyMem_ API) ] |
+1 | <----- Python memory (under PyMem manager`s control) ------> | |
__________________________________________________________________
[ Underlying general-purpose allocator (ex: C library malloc) ]
0 | <------ Virtual memory allocated for the python process -------> |
=========================================================================
_______________________________________________________________________
[ OS-specific Virtual Memory Manager (VMM) ]
-1 | <--- Kernel dynamic storage allocation & management (page-based) ---> |
__________________________________ __________________________________
[ ] [ ]
-2 | <-- Physical memory: ROM/RAM --> | | <-- Secondary storage (swap) --> |
कितने अलग अलग allocaters CPython में देखते हैं: अपने प्रश्नों, और शीर्ष पर टिप्पणी से कई के लिए एक अच्छी छोटी ASCII कला ग्राफ है?
दस्तावेज़ों के अनुसार, "कई"। आप बिल्टिन और stdlib प्रकारों में से किसी को गिन सकते हैं, फिर यदि आप वास्तव में चाहते थे तो सामान्य के मुट्ठी भर जोड़ें। लेकिन मुझे यकीन नहीं है कि यह आपको क्या बताएगा। (और यह बहुत संस्करण-विशिष्ट होगा। IIRC, यहां तक कि 3.3 वृक्ष के भीतर बदल सही संख्या, के रूप में वहाँ है कि क्या नई शैली तार तीन अलग अलग allocators या एक का उपयोग करना चाहिए के साथ एक प्रयोग किया गया था।)
प्रत्येक का कार्य क्या है?
स्तर +3 पर ऑब्जेक्ट-विशिष्ट आवंटक विशिष्ट उपयोग मामलों के लिए हैं जो अनुकूलित करने योग्य हैं। डॉक्स के रूप में कहते हैं:
उदाहरण के लिए, पूर्णांक वस्तुओं तार, tuples या शब्दकोशों से ढेर के भीतर अलग ढंग से प्रबंधित क्योंकि पूर्णांकों अलग भंडारण आवश्यकताओं और गति/अंतरिक्ष समझौतों से संकेत कर रहे हैं।
कि नीचे, स्तर 2 पर विभिन्न सामान्य समर्थन allocators (और 1.5 और हो सकता है 2.5) कम से कम कम से एक वस्तु संभाजक, एक क्षेत्र संभाजक, और एक छोटे-ब्लॉक संभाजक, कर रहे हैं आदि-लेकिन सभी पहले निजी कार्यान्वयन विवरण हैं (जिसका मतलब सी-एपीआई तक भी निजी है; जाहिर है कि यह सब पाइथन कोड के लिए निजी है)।
और उसके नीचे, कच्चा आवंटक है, जिसका कार्य ओएस से अधिक स्मृति के लिए पूछना है जब उच्च स्तरीय आवंटकों को इसकी आवश्यकता होती है।
जब malloc acutally कहा जाता है?
कच्चे स्मृति allocator (या इसके ढेर प्रबंधक) केवल बात यह है कि कभी malloc
कॉल किया जाना चाहिए। (वास्तव में, यह शायद malloc
पर भी कॉल नहीं कर सकता है; यह mmap
या VirtualAlloc
जैसे कार्यों का उपयोग कर सकता है। लेकिन मुद्दा यह है कि यह एकमात्र चीज है जो कभी भी ओएस को स्मृति के लिए पूछती है।) पाइथन के मूल में कुछ अपवाद हैं , लेकिन वे शायद ही कभी प्रासंगिक होंगे।
दस्तावेज़ स्पष्ट रूप से कहते हैं कि उच्च स्तरीय कोड को malloc
से प्राप्त स्मृति में पाइथन ऑब्जेक्ट्स पर काम करने की कोशिश नहीं करना चाहिए।
हालांकि, बहुत सारे stdlib और एक्सटेंशन मॉड्यूल हैं जो का उपयोग के साथ पायथन ऑब्जेक्ट्स के लिए करते हैं।
उदाहरण के लिए, 1000x1000 int32 मानों की एक numpy सरणी 1 मिलियन पायथन int
एस आवंटित नहीं करती है, इसलिए इसे int
आवंटक के माध्यम से जाना नहीं है। इसके बजाए, यह केवल malloc
है जो 1 मिलियन सी int
एस की सरणी है, और जब आप उन्हें एक्सेस करते हैं तो उन्हें पाइथन ऑब्जेक्ट्स में लपेटें।
कितना स्मृति अजगर स्टार्टअप पर खुद के लिए आवंटित करता है?
यह मंच-विशिष्ट है, और कोड से पता लगाने में थोड़ा मुश्किल है।हालांकि, जब मैं अपने 64-बिट मैक पर एक नया python3.3
दुभाषिया लॉन्च करता हूं, तो यह 13.1 एमबी वर्चुअल मेमोरी के साथ शुरू होता है, और लगभग तुरंत 201 एमबी तक फैलता है। तो, यह एक मोटा ballpark गाइड होना चाहिए।
क्या ऐसे नियम हैं जो इस संरचना पर डेटा संरचनाओं को पहले "डीआईबीएस" प्राप्त करते हैं?
वास्तव में नहीं, नहीं। एक दुर्भावनापूर्ण या छोटी गाड़ी ऑब्जेक्ट-विशिष्ट आवंटक तुरंत पूर्व-आवंटित स्मृति और अधिक सभी को पकड़ सकता है, और इसे रोकने के लिए कुछ भी नहीं है।
जब यह हटा दी जाती है क्या एक वस्तु के द्वारा प्रयोग किया स्मृति के लिए होता (अजगर पर अभी भी याद करने के लिए भविष्य में किसी अन्य वस्तु के लिए आवंटित करने के लिए पकड़ है, या जीसी ऊपर किसी अन्य के लिए स्मृति मुक्त करता है प्रक्रिया का उपयोग करने के लिए Google क्रोम कहें)?
यह ऑब्जेक्ट-विशिष्ट आवंटक पर वापस जाता है, जो इसे एक फ्रीलिस्ट पर रख सकता है, या इसे कच्चे आवंटक को छोड़ सकता है, जो अपनी खुद की फ्रीलिस्ट रखता है। कच्चे आवंटक लगभग कभी ओएस को वापस स्मृति जारी करता है।
यह आमतौर पर कोई अच्छी याददाश्त एक आधुनिक ओएस के लिए वापस जारी करने के लिए कारण नहीं है क्योंकि वहाँ है। यदि आपके पास आस-पास के अप्रयुक्त पृष्ठों का एक टन है, तो ओएस का वीएम सिर्फ उन्हें बाहर कर देगा यदि किसी अन्य प्रक्रिया की आवश्यकता है। और जब एक अच्छा कारण है, तो यह लगभग हमेशा एप्लिकेशन-विशिष्ट होता है, और सबसे सरल समाधान आपकी विशाल अल्पकालिक स्मृति आवश्यकताओं को प्रबंधित करने के लिए एकाधिक प्रक्रियाओं का उपयोग करना है।
जब एक जीसी शुरू हो रहा है?
यह "जीसी" द्वारा आपके मतलब पर निर्भर करता है।
CPython refcounting उपयोग करता है; हर बार जब आप किसी ऑब्जेक्ट का संदर्भ जारी करते हैं (किसी चर या एक संग्रह में स्लॉट को पुन: जोड़कर, एक चर को दायरे से बाहर जाने दें, आदि), यदि यह अंतिम संदर्भ था, तो इसे तुरंत साफ़ कर दिया जाएगा। यह दस्तावेज़ों में Reference Counting अनुभाग में समझाया गया है।
हालांकि, वहाँ refcounting साथ एक समस्या है: दो वस्तुओं एक दूसरे के संदर्भ अगर, तब भी जब सब बाहर संदर्भ चले जाओ, वे अभी भी साफ नहीं किया जाएगा। इसलिए, सीपीथन में हमेशा एक चक्र कलेक्टर होता है जो समय-समय पर ऑब्जेक्ट्स के चक्रों की तलाश में वस्तुओं को चलाता है जो एक-दूसरे को संदर्भित करते हैं, लेकिन कोई बाहरी संदर्भ नहीं है। (यह थोड़ा और जटिल है, लेकिन यह मूल विचार है।) gc
मॉड्यूल के लिए दस्तावेज़ों में यह पूरी तरह से समझाया गया है। कलेक्टर तब चला सकता है जब आप इसे स्पष्ट रूप से पूछते हैं, जब फ्रीलिस्ट कम हो रहे हैं, या जब यह लंबे समय तक नहीं चलता है; यह गतिशील है और कुछ हद तक विन्यास योग्य है, इसलिए "कब" के लिए एक विशिष्ट उत्तर देना मुश्किल है।
सूचियों गतिशील सरणियों, जो वे स्मृति का एक सन्निहित टुकड़ा की जरूरत का मतलब है। इसका अर्थ यह है कि यदि मैं किसी ऑब्जेक्ट को किसी सूची में जोड़ने का प्रयास करता हूं, जिसका अंतर्निहित-सी-डेटा-स्ट्रक्चर सरणी विस्तारित नहीं किया जा सकता है, तो सरणी को स्मृति के एक अलग भाग पर कॉपी किया जाता है, जहां एक बड़ा संगत ब्लॉक उपलब्ध होता है। तो जब मैं एक सूची शुरू करता हूं तो इस सरणी में कितनी जगह आवंटित की जाती है?
इसके लिए कोड अधिकतर listobject.c
के अंदर है।यह जटिल है; अस्थायी इंटरमीडिएट सूचियां बनाने और गैर-इन-प्लेस सॉर्टिंग के लिए टाइम्सोर्ट द्वारा उपयोग किए जाने वाले कोड जैसे विशेष मामलों का एक गुच्छा है। लेकिन आखिरकार, कोड का कुछ टुकड़ा तय करता है कि उसे एन पॉइंटर्स के लिए कमरे की जरूरत है।
यह भी विशेष रूप से दिलचस्प नहीं है। अधिकांश सूचियां या तो कभी भी विस्तारित नहीं होती हैं, या मूल आकार से कहीं अधिक विस्तारित नहीं होती हैं, इसलिए प्रारंभिक सूचियों के लिए स्टार्ट अपशिष्ट मेमोरी पर अतिरिक्त आवंटन करना और सबसे बढ़ती सूचियों के लिए बहुत मदद नहीं करता है। तो, पायथन इसे रूढ़िवादी खेलता है। मेरा मानना है कि यह अपने आंतरिक फ्रीलिस्ट को देखकर शुरू होता है जो एन पॉइंटर्स से बहुत बड़ा नहीं है (यह आसन्न मुक्त सूची भंडारण को भी समेकित कर सकता है; मुझे नहीं पता कि यह क्या करता है), इसलिए यह कभी-कभी थोड़ा सा आवंटित हो सकता है, लेकिन आम तौर पर यह ऐसा नहीं करता। सटीक कोड PyList_New
में होना चाहिए।
किसी भी दर पर, यदि सूची आवंटक के फ्रीलिस्ट में कोई जगह नहीं है, तो यह ऑब्जेक्ट आवंटक को छोड़ देता है, और इसलिए स्तरों के माध्यम से; यह 0 स्तर पर टक्कर मार सकता है, लेकिन आमतौर पर यह नहीं करता है।
नई सरणी को कितनी अतिरिक्त जगह आवंटित की जाती है, जिसमें अब पुरानी सूची और संलग्न वस्तु है?
यह list_resize
में संभाला जाता है, और यह दिलचस्प हिस्सा है।
list.append
वर्गवार होने से बचने का एकमात्र तरीका ज्यामितीय रूप से आवंटित करना है। पहले कुछ विस्तारों के लिए एक कारक (जैसे 1.2) कचरे के रास्ते से बहुत कम समय तक ओवरलैकोटिंग; बहुत बड़े कारकों (1.6 की तरह) कचरे का बहुत बड़ा उपयोग बहुत बड़े सरणी के लिए बहुत अधिक जगह का उपयोग कर। पाइथन इसे अनुक्रम का उपयोग करके संभालता है जो 2.0 पर शुरू होता है लेकिन जल्दी से 1.25 के आसपास कहीं भी परिवर्तित हो जाता है।
विकास पैटर्न है:: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
आप 3.3 स्रोत के अनुसार विशेष रूप से sorted
के बारे में नहीं पूछा, लेकिन मुझे पता है कि यही आपको प्रेरित करता है।
याद रखें कि टाइम्सॉर्ट मुख्य रूप से एक विलय प्रकार है, जिसमें छोटे उपन्यासकारों के लिए सम्मिलन प्रकार है जो पहले से सॉर्ट नहीं किए गए हैं। इसलिए, इसके अधिकांश परिचालनों में आकार 2 एन की एक नई सूची आवंटित करना और आकार एन की दो सूचियों को मुक्त करना शामिल है। इसलिए, यह लगभग स्थान के रूप में हो सकता है - आवंटन-कुशल होने पर प्रतिलिपि बनाते समय यह जगह होगी। ओ (लॉग एन) अपशिष्ट पर निर्भर है, लेकिन यह आम तौर पर ऐसा कारक नहीं है जो प्रतिलिपि बनाने को धीमा कर देता है।
डाउनवोट क्यों? मैं एक कानूनी सवाल देखता हूं कि एक बार मूर्ख नहीं है, बेवकूफ़ है। – RickyA
शायद क्योंकि यह अविश्वसनीय रूप से व्यापक है। यहां कम से कम 6 प्रश्न हैं। – user2357112
सीपीआई दस्तावेज के [मेमोरी प्रबंधन] (http://docs.python.org/3/c-api/memory.html) अध्याय में इसका उत्तर दिया गया है। इसमें से कुछ आप से पूछ रहे हैं ("... कई ऑब्जेक्ट-विशिष्ट आवंटकों" आपको यह नहीं बताता कि कितने "कई" हैं), लेकिन आपको एक विशिष्ट संस्करण और डाइविंग चुनने के बिना और अधिक जानकारी नहीं मिल रही है कोड में – abarnert