ओएसएक्स पर गतिविधि मॉनिटर आपको वास्तव में एक बहुत अच्छा अनुमान देता है।
निजी मेमोरी निश्चित स्मृति के लिए है जो केवल आपके आवेदन द्वारा उपयोग की जाती है। जैसे स्टेक मेमोरी और सभी मेमोरी गतिशील रूप से malloc() और तुलनीय कार्यों/विधियों (उद्देश्य-सी के लिए आवंट विधि) का उपयोग करके आरक्षित निजी स्मृति है। यदि आप कांटा, निजी स्मृति आपके बच्चे के साथ साझा की जाएगी, लेकिन कॉपी-ऑन-राइट चिह्नित है। इसका अर्थ यह है कि जब तक किसी पृष्ठ को किसी भी प्रक्रिया (माता-पिता या बच्चे) द्वारा संशोधित नहीं किया जाता है, तब तक यह उनके बीच साझा किया जाता है। जैसे ही प्रक्रिया किसी भी पृष्ठ को संशोधित करती है, इस पृष्ठ को संशोधित करने से पहले इसकी प्रतिलिपि बनाई जाती है। यहां तक कि यह स्मृति फोर्क बच्चों के साथ साझा की जाती है (और यह केवल कांटा बच्चों के साथ साझा किया जा सकता है), यह अभी भी "निजी" स्मृति के रूप में दिखाया गया है, क्योंकि सबसे बुरे मामले में, इसका प्रत्येक पृष्ठ संशोधित हो जाएगा (जल्दी या बाद में) और फिर यह फिर से प्रत्येक प्रक्रिया के लिए निजी है।
साझा स्मृति या तो स्मृति जो वर्तमान में साझा की गई है (उसी पृष्ठ को विभिन्न प्रक्रियाओं की वर्चुअल प्रोसेस स्पेस में दिखाई दे रहा है) या भविष्य में साझा होने की संभावना है (उदाहरण के लिए केवल पढ़ने की स्मृति, क्योंकि कोई कारण नहीं है केवल पढ़ने के लिए स्मृति साझा नहीं करने के लिए)। कम से कम इस तरह मैं ऐप्पल से कुछ कमांड लाइन टूल्स के स्रोत कोड को पढ़ता हूं। तो यदि आप mmap (या तुलनात्मक कॉल जो एक ही मेमोरी को एकाधिक प्रक्रियाओं में मैप करते हैं) का उपयोग करके प्रक्रियाओं के बीच स्मृति साझा करते हैं, तो यह साझा स्मृति होगी। हालांकि निष्पादन योग्य कोड स्वयं भी स्मृति साझा किया जाता है, क्योंकि यदि आपके आवेदन का एक और उदाहरण शुरू हो गया है, तो ऐसा कोई कारण नहीं है कि यह पहले से ही स्मृति में लोड किए गए कोड को साझा नहीं कर सकता है (निष्पादन योग्य कोड पृष्ठ केवल डिफ़ॉल्ट रूप से पढ़े जाते हैं, जब तक कि आप अपना भाग नहीं लेते एक डीबगर में ऐप)। इस प्रकार साझा मेमोरी वास्तव में आपके एप्लिकेशन द्वारा उपयोग की जाने वाली मेमोरी है, बस निजी की तरह, लेकिन इसे अतिरिक्त रूप से किसी अन्य प्रक्रिया के साथ साझा किया जा सकता है (या हो सकता है, लेकिन यह आपके आवेदन की ओर क्यों नहीं गिना जाएगा?)
वास्तविक स्मृति आपकी प्रक्रिया में वर्तमान में "असाइन की गई" रैम की मात्रा है, चाहे कोई भी निजी या साझा न हो। यह वास्तव में निजी और साझा की राशि हो सकती है, लेकिन आमतौर पर यह नहीं है। वर्तमान में इसकी आवश्यकता के मुकाबले आपकी प्रक्रिया में अधिक स्मृति आवंटित हो सकती है (यह भविष्य में अधिक स्मृति के लिए अनुरोधों को गति देता है), लेकिन यह सिस्टम को कोई नुकसान नहीं है। यदि सिस्टम को स्वैपिंग शुरू होने से पहले किसी अन्य प्रक्रिया को मेमोरी की आवश्यकता होती है और कोई भी मुफ्त मेमोरी उपलब्ध नहीं होती है, तो यह अतिरिक्त प्रक्रिया को आपकी प्रक्रिया से दूर ले जाएगी और इसे एक और प्रक्रिया सौंपेगी (जो एक तेज़ और दर्द रहित ऑपरेशन है); इसके लिए आपकी अगली मॉलोक कॉल कुछ हद तक धीमी हो सकती है। वास्तविक स्मृति निजी और भौतिक स्मृति से भी छोटी हो सकती है; ऐसा इसलिए है क्योंकि यदि आपकी प्रक्रिया सिस्टम से स्मृति का अनुरोध करती है, तो इसे केवल "वर्चुअल मेमोरी" प्राप्त होगी। जब तक आप इसका उपयोग नहीं करते हैं, तब तक यह वर्चुअल मेमोरी किसी भी वास्तविक मेमोरी पेज से जुड़ी नहीं है (इसलिए मैलोक 10 एमबी मेमोरी, इसके केवल एक बाइट का उपयोग करें, आपकी प्रक्रिया को केवल एक ही पेज, 4096 बाइट, स्मृति आवंटित किया जाएगा - शेष केवल तभी असाइन किया जाता है जब आपको वास्तव में इसकी आवश्यकता हो)। स्वैप की गई अतिरिक्त मेमोरी वास्तविक स्मृति की ओर गिनती नहीं कर सकती है (इस बारे में निश्चित नहीं है), लेकिन यह साझा और निजी मेमोरी की ओर गिना जाएगा।
वर्चुअल मेमोरी उन सभी पता ब्लॉकों का योग है जो आपके ऐप्स प्रक्रिया स्थान में मान्य मानी जाती हैं। ये पते भौतिक स्मृति से जुड़ा हो सकता है (जो कि फिर से निजी या साझा किया जाता है), या वे शायद नहीं, लेकिन उस स्थिति में जैसे ही आप पते का उपयोग करते हैं, वे भौतिक स्मृति से जुड़े रहेंगे। ज्ञात पतों के बाहर मेमोरी पतों तक पहुंचने से सिगबस हो जाएगा और आपका ऐप क्रैश हो जाएगा। जब स्मृति बदली है, यह स्मृति के लिए वर्चुअल ऐड्रेस स्पेस मान्य रहती है और उन पतों तक पहुँचने का कारण बनता है स्मृति में वापस बदली किए जाने की
निष्कर्ष:।
अपने अनुप्रयोग स्पष्ट या परोक्ष साझा स्मृति का उपयोग नहीं करता है, तो निजी स्मृति स्टैक आकार (या मल्टीथ्रेड किए गए आकार) के कारण आपके ऐप की मेमोरी की मात्रा है और मॉलोक() कॉल की वजह से आपने गतिशील मेमोरी के लिए बनाया है। उस मामले में आपको साझा या वास्तविक स्मृति के लिए बहुत कुछ परवाह नहीं है।
यदि आपका ऐप साझा मेमोरी का उपयोग करता है, और इसमें एक ग्राफिकल यूआई शामिल है, जहां उदाहरण के लिए आपके एप्लिकेशन और विंडोसेवर के बीच मेमोरी साझा की जाती है, तो हो सकता है कि आप साझा स्मृति को भी देखें। एक बहुत ही उच्च साझा स्मृति संख्या का मतलब हो सकता है कि इस समय आपके पास स्मृति में लोड किए गए बहुत से ग्राफिकल संसाधन हैं।
वास्तविक स्मृति ऐप विकास के लिए बहुत कम रुचि है। यदि यह साझा और निजी के योग से बड़ा है, तो इसका मतलब यह नहीं है कि सिस्टम आपकी प्रक्रिया से दूर स्मृति पर आलसी है। यदि यह छोटा है, तो आपकी प्रक्रिया ने वास्तव में इसकी आवश्यकता से अधिक मेमोरी का अनुरोध किया है, जो तब तक बुरा नहीं है, जब तक आप सभी अनुरोधित मेमोरी का उपयोग नहीं करते हैं, तब तक आप सिस्टम से स्मृति को "चोरी" नहीं कर रहे हैं।यदि यह साझा और निजी की राशि से काफी छोटा है, आप केवल कम स्मृति अनुरोध करने के लिए जहां संभव हो, के रूप में आप कर रहे हैं एक बिट से अधिक-का अनुरोध फिर से स्मृति (, यह बुरा नहीं है पर विचार कर सकते हैं, लेकिन यह है कि अपने कोड नहीं है मुझसे कहता है कम से कम स्मृति के उपयोग के लिए अनुकूलित और अगर यह पार मंच है, अन्य प्लेटफार्मों इस तरह के एक परिष्कृत स्मृति से निपटने नहीं हो सकता है, इसलिए ताकि आप उदाहरण के लिए कुछ बड़े लोगों के बजाय कई छोटे ब्लॉक, या मुक्त स्मृति alloc करने के लिए एक बहुत जल्दी ही पसंद करते हैं, और हो सकता है पर)।
आप अभी भी है कि सभी जानकारी से खुश नहीं हैं, तो आप भी अधिक जानकारी प्राप्त कर सकते हैं। टर्मिनल खोलें और चलाएं:
sudo vmmap <pid>
आपकी प्रक्रिया की प्रक्रिया आईडी कहां है। यह हर आरंभ और अंत पते के साथ अपने प्रक्रिया अंतरिक्ष में स्मृति के ब्लॉक के लिए आप के आंकड़े दिखाएगी। यह भी आपको बता देंगे, जहां इस स्मृति से आया है (ए मैप की फ़ाइल? स्मृति स्टैक? Malloc'ed स्मृति? अपने निष्पादन का एक __DATA या __TEXT अनुभाग?), कितना बड़ा यह KB में है, अधिकारों का उपयोग और क्या यह निजी है, साझा या कॉपी-ऑन-राइट। यदि यह किसी फ़ाइल से मैप किया गया है, तो यह आपको फ़ाइल का मार्ग भी देगा।
आप केवल "वास्तविक" RAM उपयोग करना चाहते हैं, का उपयोग
sudo vmmap -resident <pid>
अब यह हर स्मृति ब्लॉक के लिए दिखाई देगा कितना बड़ा स्मृति ब्लॉक लगभग है और इसके बारे में कितना वास्तव में वर्तमान में भौतिक स्मृति में मौजूद है।
प्रत्येक डंप के अंत में भी अलग स्मृति प्रकार की रकम के साथ एक सिंहावलोकन तालिका है। यह तालिका अभी मेरे सिस्टम पर फ़ायरफ़ॉक्स के लिए इस तरह दिखती है:
REGION TYPE [ VIRTUAL/RESIDENT]
=========== [ =======/========]
ATS (font support) [ 33.8M/ 2496K]
CG backing stores [ 5588K/ 5460K]
CG image [ 20K/ 20K]
CG raster data [ 576K/ 576K]
CG shared images [ 2572K/ 2404K]
Carbon [ 1516K/ 1516K]
CoreGraphics [ 8K/ 8K]
IOKit [ 256.0M/ 0K]
MALLOC [ 256.9M/ 247.2M]
Memory tag=240 [ 4K/ 4K]
Memory tag=242 [ 12K/ 12K]
Memory tag=243 [ 8K/ 8K]
Memory tag=249 [ 156K/ 76K]
STACK GUARD [ 101.2M/ 9908K]
Stack [ 14.0M/ 248K]
VM_ALLOCATE [ 25.9M/ 25.6M]
__DATA [ 6752K/ 3808K]
__DATA/__OBJC [ 28K/ 28K]
__IMAGE [ 1240K/ 112K]
__IMPORT [ 104K/ 104K]
__LINKEDIT [ 30.7M/ 3184K]
__OBJC [ 1388K/ 1336K]
__OBJC/__DATA [ 72K/ 72K]
__PAGEZERO [ 4K/ 0K]
__TEXT [ 108.6M/ 63.5M]
__UNICODE [ 536K/ 512K]
mapped file [ 118.8M/ 50.8M]
shared memory [ 300K/ 276K]
shared pmap [ 6396K/ 3120K]
यह हमें क्या बताता है? जैसे फ़ायरफ़ॉक्स बाइनरी और लोड होने वाली सभी लाइब्रेरी में उनके __TEXT अनुभागों में 108 एमबी डेटा एक साथ है, लेकिन वर्तमान में उनमें से केवल 63 एमबी स्मृति में निवासी हैं। फ़ॉन्ट समर्थन (एटीएस) को 33 एमबी की आवश्यकता है, लेकिन केवल 2.5 एमबी वास्तव में स्मृति में हैं। यह 5 एमबी सीजी बैकिंग स्टोर्स, सीजी = कोर ग्राफिक्स से थोड़ा अधिक उपयोग करता है, जो सबसे अधिक संभावना खिड़की सामग्री, बटन, छवियों और अन्य डेटा हैं जो तेजी से ड्राइंग के लिए कैश किए जाते हैं। उसने मॉलोक कॉल के माध्यम से 256 एमबी का अनुरोध किया है और वर्तमान में 247 एमबी मेमोरी पेजों में मैप किए गए हैं। इसमें 14 एमबी स्पेस स्टैक्स के लिए आरक्षित है, लेकिन अभी केवल 248 केबी स्टैक स्पेस वास्तव में उपयोग में है।
vmmap भी तालिका
ReadOnly portion of Libraries: Total=139.3M resident=66.6M(48%) swapped_out_or_unallocated=72.7M(52%)
Writable regions: Total=595.4M written=201.8M(34%) resident=283.1M(48%) swapped_out=0K(0%) unallocated=312.3M(52%)
ऊपर एक अच्छा सारांश है और यह ओएस एक्स का एक दिलचस्प पहलू पता चलता है: केवल पढ़ने के लिए स्मृति के लिए यह कोई भूमिका निभाता है अगर यह बदली या बस आवंटित नहीं की गई है; केवल निवासी और निवासी नहीं है। लिखने योग्य स्मृति के लिए यह एक फर्क नहीं पड़ता (मेरे मामले में सभी से अनुरोध किया स्मृति के 52% इस्तेमाल किया गया कभी नहीं किया है और इस तरह के आवंटित नहीं की गई है, स्मृति के 0% डिस्क के लिए बदली गई है)
वास्तव में "वास्तविक स्मृति उपयोग" क्या है दे देंगे? आपकी सूची के आधार पर, एकल प्रक्रिया के लिए स्मृति उपयोग का विचार या तो बेकार या मनमाना है। – BCS
मैं "वास्तविक स्मृति उपयोग" को भौतिक स्मृति की मात्रा (लेकिन स्वैप नहीं) के रूप में परिभाषित करता हूं जो कि अगर मैं 'मार -9' दी गई प्रक्रिया को छोड़ दूंगा। मेरा मानना है कि यह संख्या किसी प्रक्रिया के लिए आरएसएस और पीएसएस मूल्यों के बीच कहीं कहीं होनी चाहिए। –
@ हांगली: हालांकि एक पुराना धागा है, मैं आश्चर्यचकित हूं कि क्यों लिनप्रोकस फ्रीबीएसडी के लिए यहां किसी भी व्यक्ति द्वारा सुझाए गए समाधान का हिस्सा नहीं था। क्या इसके लिए कोई विशिष्ट कारण है? मैंने वैसे भी पूरा होने के लिए उस उत्तर को जोड़ा है। – Arvind