linux - एप्लिकेशन या प्रक्रिया के वास्तविक मेमोरी उपयोग को कैसे मापें?




memory process (20)

यह प्रश्न here बहुत विस्तार से शामिल है।

लिनक्स में किसी एप्लिकेशन या प्रक्रिया के मेमोरी उपयोग को आप कैसे मापते हैं?

लिनक्स पर स्मृति उपयोग को समझने के ब्लॉग आलेख से, ps इस इरादे के लिए उपयोग करने के लिए एक सटीक उपकरण नहीं है।

ps क्यों "गलत" है

इस पर निर्भर करते हुए कि आप इसे कैसे देखते हैं, ps प्रक्रियाओं के वास्तविक स्मृति उपयोग की रिपोर्ट नहीं कर रहा है। वास्तव में यह क्या कर रहा है यह दिखा रहा है कि प्रत्येक प्रक्रिया कितनी वास्तविक मेमोरी लेगी यदि यह एकमात्र प्रक्रिया चल रही थी । बेशक, एक विशिष्ट लिनक्स मशीन में किसी भी समय चलने वाली कई दर्जन प्रक्रियाएं होती हैं, जिसका अर्थ है कि ps द्वारा रिपोर्ट किए गए वीएसजेड और आरएसएस संख्या लगभग निश्चित रूप से गलत हैं


अधिक "वास्तविक दुनिया" उपयोग का एक अच्छा परीक्षण एप्लिकेशन खोलना है, फिर vmstat -s चलाएं और "सक्रिय स्मृति" आंकड़े की जांच करें। एप्लिकेशन बंद करें, कुछ सेकंड प्रतीक्षा करें और फिर vmstat -s चलाएं। हालांकि ऐप द्वारा उपयोग में स्पष्ट रूप से बहुत सक्रिय स्मृति को मुक्त किया गया था।


आपके उत्तरों में सूचीबद्ध समाधानों के अलावा, आप लिनक्स कमांड "टॉप" का उपयोग कर सकते हैं; यह चल रहे सिस्टम के गतिशील रीयल-टाइम दृश्य प्रदान करता है, यह प्रत्येक प्रोग्राम के साथ-साथ प्रतिशत में, संपूर्ण सिस्टम के लिए सीपीयू और मेमोरी उपयोग देता है:

top

एक प्रोग्राम पिड द्वारा फ़िल्टर करने के लिए:

top -p <PID>

प्रोग्राम नाम से फ़िल्टर करने के लिए:

top | grep <PROCESS NAME>

"टॉप" कुछ फ़ील्ड भी प्रदान करता है जैसे कि:

वीआईआरटी - आभासी छवि (केबी): कार्य द्वारा उपयोग की जाने वाली वर्चुअल मेमोरी की कुल राशि

आरईएस - निवासी आकार (केबी): गैर-स्वैच्छिक भौतिक स्मृति एक कार्य का उपयोग किया गया है; आरईएस = कोड + डेटा।

डेटा - डेटा + स्टैक आकार (केबी): निष्पादन योग्य कोड के अलावा समर्पित भौतिक स्मृति की मात्रा, जिसे 'डेटा निवासी सेट' आकार या डीआरएस भी कहा जाता है।

एसएचआर - साझा मेम आकार (केबी): किसी कार्य द्वारा उपयोग की गई साझा स्मृति की मात्रा। यह बस स्मृति को प्रतिबिंबित करता है जिसे संभावित रूप से अन्य प्रक्रियाओं के साथ साझा किया जा सकता है।

here संदर्भ।


इसके लिए कोई जवाब नहीं है क्योंकि आप निश्चित रूप से एक प्रक्रिया का उपयोग करने वाली स्मृति की मात्रा को इंगित नहीं कर सकते हैं। लिनक्स के तहत अधिकांश प्रक्रियाएं साझा पुस्तकालयों का उपयोग करती हैं। उदाहरण के लिए, मान लें कि आप 'ls' प्रक्रिया के लिए स्मृति उपयोग की गणना करना चाहते हैं। क्या आप केवल निष्पादन योग्य 'एलएस' द्वारा उपयोग की जाने वाली स्मृति को गिनते हैं (यदि आप इसे अलग कर सकते हैं)? Libc के बारे में कैसे? या इन सभी अन्य libs जिन्हें 'एलएस' चलाने की आवश्यकता है?

linux-gate.so.1 =>  (0x00ccb000)
librt.so.1 => /lib/librt.so.1 (0x06bc7000)
libacl.so.1 => /lib/libacl.so.1 (0x00230000)
libselinux.so.1 => /lib/libselinux.so.1 (0x00162000)
libc.so.6 => /lib/libc.so.6 (0x00b40000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00cb4000)
/lib/ld-linux.so.2 (0x00b1d000)
libattr.so.1 => /lib/libattr.so.1 (0x00229000)
libdl.so.2 => /lib/libdl.so.2 (0x00cae000)
libsepol.so.1 => /lib/libsepol.so.1 (0x0011a000)

आप तर्क दे सकते हैं कि उन्हें अन्य प्रक्रियाओं द्वारा साझा किया जाता है, लेकिन 'ls' को लोड किए बिना सिस्टम पर नहीं चलाया जा सकता है।

साथ ही, यदि आपको यह जानने की आवश्यकता है कि क्षमता योजना बनाने के लिए किसी प्रक्रिया को कितनी मेमोरी की आवश्यकता है, तो आपको गणना करना होगा कि प्रक्रिया की प्रत्येक अतिरिक्त प्रति कितनी उपयोग करती है। मुझे लगता है कि / proc / pID / स्थिति आपको एक ही समय में स्मृति उपयोग की पर्याप्त जानकारी दे सकती है। दूसरी तरफ, वाल्ग्रिंड आपको कार्यक्रम के पूरे जीवनकाल में स्मृति उपयोग की बेहतर प्रोफ़ाइल देगा


निश्चित रूप से बताना मुश्किल है, लेकिन यहां दो "करीबी" चीजें हैं जो मदद कर सकती हैं।

$ ps aux 

आपको वर्चुअल साइज (वीएसजेड) देगा

आप /proc/$pid/status जाकर / proc फ़ाइल-सिस्टम से विस्तृत आंकड़े भी प्राप्त कर सकते हैं

सबसे महत्वपूर्ण VMSize है, जो ps aux देता है के करीब होना चाहिए।

/proc/19420$ cat status
Name:   firefox
State:  S (sleeping)
Tgid:   19420
Pid:    19420
PPid:   1
TracerPid:  0
Uid:    1000    1000    1000    1000
Gid:    1000    1000    1000    1000
FDSize: 256
Groups: 4 6 20 24 25 29 30 44 46 107 109 115 124 1000 
VmPeak:   222956 kB
VmSize:   212520 kB
VmLck:         0 kB
VmHWM:    127912 kB
VmRSS:    118768 kB
VmData:   170180 kB
VmStk:       228 kB
VmExe:        28 kB
VmLib:     35424 kB
VmPTE:       184 kB
Threads:    8
SigQ:   0/16382
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000020001000
SigCgt: 000000018000442f
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
Cpus_allowed:   03
Mems_allowed:   1
voluntary_ctxt_switches:    63422
nonvoluntary_ctxt_switches: 7171


यदि आपका कोड सी या सी ++ में है तो आप getrusage() का उपयोग करने में सक्षम हो सकते हैं जो आपको आपकी प्रक्रिया के स्मृति और समय के उपयोग के बारे में विभिन्न आंकड़े देता है।

सभी प्लेटफॉर्म इस का समर्थन नहीं करते हैं और स्मृति-उपयोग विकल्पों के लिए 0 मान वापस कर देंगे।

इसके बजाय आप /proc/[pid]/statm (जहां [pid] में आपकी getpid() आईडी द्वारा प्रतिस्थापित की गई वर्चुअल फ़ाइल को देख सकते हैं। आप इसे getpid() से प्राप्त कर सकते हैं।

यह फ़ाइल 7 पूर्णांक वाले टेक्स्ट फ़ाइल की तरह दिखाई देगी। आप शायद इस फ़ाइल में पहले (सभी मेमोरी उपयोग) और छठे (डेटा मेमोरी उपयोग) संख्याओं में सबसे अधिक रुचि रखते हैं।


यदि आपके पास इसे चलाने का समय है तो वालग्रिंड अद्भुत है। valgrind --tool=massif सही समाधान है।

हालांकि, मैं बड़े उदाहरण चलाने शुरू कर रहा हूं, और वाल्ग्रिंड का उपयोग अब व्यावहारिक नहीं है। क्या प्रोग्राम के अधिकतम मेमोरी उपयोग (मॉड्यूल पेज पेज और साझा पेज) को बताने का कोई तरीका है?

एक वास्तविक यूनिक्स सिस्टम पर, /usr/bin/time -v काम करता है। लिनक्स पर, हालांकि, यह काम नहीं करता है।


लिनक्स के हाल के संस्करणों में, स्मैप्स सबसिस्टम का उपयोग करें। उदाहरण के लिए, 1234 के पीआईडी ​​के साथ एक प्रक्रिया के लिए:

cat /proc/1234/smaps

यह आपको बताएगा कि उस समय कितनी मेमोरी उपयोग कर रही है। इससे भी महत्वपूर्ण बात यह है कि यह स्मृति को निजी और साझा में विभाजित कर देगा, ताकि आप प्रोग्राम के कई उदाहरणों के बीच साझा स्मृति को शामिल किए बिना प्रोग्राम के आपके उदाहरण का कितना मेमोरी उपयोग कर सकें।


/prox/xxx/numa_maps gives some info there: N0=??? N1=???. But this result might be lower than the actual result, as it only count those which have been touched.


smem प्रयोग करें, जो पीएस का एक विकल्प है जो प्रति प्रक्रिया यूएसएस और पीएसएस की गणना करता है। आप जो चाहते हैं वह शायद पीएसएस है।

  • यूएसएस - अद्वितीय सेट आकार। यह उस प्रक्रिया के लिए अनन्य स्मृति की मात्रा है (इसे अद्वितीय स्मृति के लिए यू के रूप में सोचें)। इसमें साझा स्मृति शामिल नहीं है। इस प्रकार यह एक प्रक्रिया का उपयोग करने वाली स्मृति की मात्रा को कम करेगा, लेकिन जब आप साझा स्मृति को अनदेखा करना चाहते हैं तो सहायक होता है।

  • पीएसएस - आनुपातिक सेट आकार। आप यही चाहते हैं। यह उस स्मृति को साझा करने वाली अन्य प्रक्रियाओं की संख्या से विभाजित अपनी साझा स्मृति के अनुपात के साथ अद्वितीय स्मृति (यूएसएस) को एक साथ जोड़ता है। इस प्रकार यह आपको एक सटीक प्रतिनिधित्व देगा कि प्रति प्रक्रिया कितनी वास्तविक भौतिक स्मृति का उपयोग किया जा रहा है - साझा स्मृति को वास्तव में साझा के रूप में दर्शाया गया है। पी के बारे में सोचें शारीरिक स्मृति के लिए।

यह आरएसएस और अन्य utilties द्वारा रिपोर्ट के रूप में आरएसएस की तुलना कैसे करता है:

  • आरएसएस - निवासी सेट आकार। यह प्रत्येक प्रक्रिया द्वारा उपयोग की जाने वाली साझा मेमोरी प्लस अनशेर्ड मेमोरी की मात्रा है। यदि कोई प्रक्रिया मेमोरी साझा करती है, तो यह वास्तव में उपयोग की जाने वाली मेमोरी की मात्रा को अधिक से अधिक रिपोर्ट करेगा, क्योंकि एक ही साझा मेमोरी को एक से अधिक बार गिना जाएगा - एक ही मेमोरी साझा करने वाली एक दूसरे प्रक्रिया में फिर से दिखाई दे रहा है। इस प्रकार यह काफी अविश्वसनीय है, खासकर जब उच्च-स्मृति प्रक्रियाओं में बहुत सारे कांटे होते हैं - जो सर्वर में आम है, अपाचे या PHP (फास्टसी / एफपीएम) प्रक्रियाओं जैसी चीजों के साथ।

नोटिस: स्मेम (वैकल्पिक रूप से) आउटपुट ग्राफ़ जैसे पाई चार्ट और इसी तरह के ग्राफ भी कर सकते हैं। आईएमओ आपको उसमें से किसी की आवश्यकता नहीं है। यदि आप इसे कमांड लाइन से उपयोग करना चाहते हैं जैसे आप ps -A v का उपयोग कर सकते हैं, तो आपको पायथन-मैटलप्लिपिब अनुशंसित निर्भरता स्थापित करने की आवश्यकता नहीं है।


ps या इसी तरह के औजारों के साथ आपको केवल उस प्रक्रिया द्वारा आवंटित स्मृति पृष्ठों की मात्रा मिल जाएगी। यह संख्या सही है, लेकिन:

  • आवेदन द्वारा उपयोग की जाने वाली स्मृति की वास्तविक मात्रा को प्रतिबिंबित नहीं करता है, केवल इसके लिए आरक्षित स्मृति की मात्रा

  • पृष्ठों को साझा किए जाने पर भ्रामक हो सकता है, उदाहरण के लिए कई धागे या गतिशील रूप से जुड़े पुस्तकालयों का उपयोग करके

यदि आप वास्तव में जानना चाहते हैं कि आपका एप्लिकेशन वास्तव में कितनी मेमोरी का उपयोग करता है, तो आपको इसे प्रोफाइलर के भीतर चलाने की आवश्यकता है। उदाहरण के लिए, valgrind आपको आपके प्रोग्राम में संभावित मेमोरी लीक के बारे में उपयोग की जाने वाली स्मृति की मात्रा के बारे में अंतर्दृष्टि प्रदान कर सकता है। Valgrind के ढेर प्रोफाइलर उपकरण 'massif' कहा जाता है:

Massif एक ढेर प्रोफाइलर है। यह एक कार्यक्रम के ढेर के नियमित स्नैपशॉट लेकर विस्तृत ढेर प्रोफाइलिंग करता है। यह समय के साथ हीप उपयोग दिखाते हुए एक ग्राफ उत्पन्न करता है, जिसमें अधिकांश स्मृति आवंटन के लिए कार्यक्रम के कौन से हिस्से जिम्मेदार होते हैं, इस बारे में जानकारी शामिल है। ग्राफ को एक टेक्स्ट या HTML फ़ाइल द्वारा पूरक किया गया है जिसमें यह निर्धारित करने के लिए अधिक जानकारी शामिल है कि सबसे अधिक स्मृति आवंटित की जा रही है। मासफ सामान्य से 20x धीमी गति से प्रोग्राम चलाता है।

जैसा कि वाल्ग्रिंड दस्तावेज में बताया गया है, आपको प्रोग्राम को वालग्रिंड के माध्यम से चलाने की आवश्यकता है:

valgrind --tool=massif <executable> <arguments>

मैसिफ़ मेमोरी उपयोग स्नैपशॉट्स का एक डंप लिखता है (उदाहरण के लिए massif.out.12345 )। ये प्रदान करते हैं, (1) प्रत्येक स्नैपशॉट के लिए स्मृति उपयोग की एक समयरेखा, (2), आपके प्रोग्राम मेमोरी में कहां आवंटित किया गया था इसका एक रिकॉर्ड। इन फ़ाइलों का विश्लेषण करने के लिए एक शानदार ग्राफिकल उपकरण massif-visualizer । लेकिन मैंने ms_print पाया, एक सरल पाठ-आधारित उपकरण, ms_print साथ भेज दिया गया है, जो पहले से ही बहुत मददगार है।

मेमोरी लीक खोजने के लिए, memcheck के (डिफ़ॉल्ट) memcheck टूल का उपयोग करें।


Based on answer to a related question .

You may use SNMP to get the memory and cpu usage of a process in a particular device in network :)

Requirements:

  • the device running the process should have snmp installed and running
  • snmp should be configured to accept requests from where you will run the script below(it may be configured in snmpd.conf)
  • you should know the process id(pid) of the process you want to monitor

Notes:

  • HOST-RESOURCES-MIB::hrSWRunPerfCPU is the number of centi-seconds of the total system's CPU resources consumed by this process. Note that on a multi-processor system, this value may increment by more than one centi-second in one centi-second of real (wall clock) time.

  • HOST-RESOURCES-MIB::hrSWRunPerfMem is the total amount of real system memory allocated to this process.

**

Process monitoring script:

**

echo "IP: "
read ip
echo "specfiy pid: "
read pid
echo "interval in seconds:"
read interval

while [ 1 ]
do
    date
    snmpget -v2c -c public $ip HOST-RESOURCES-MIB::hrSWRunPerfCPU.$pid
    snmpget -v2c -c public $ip HOST-RESOURCES-MIB::hrSWRunPerfMem.$pid
    sleep $interval;
done

वालग्रिंड विस्तृत जानकारी दिखा सकता है लेकिन यह लक्ष्य अनुप्रयोग को काफी हद तक धीमा कर देता है, और अधिकांश समय यह ऐप के व्यवहार को बदलता है।
Exmap कुछ ऐसा था जो मुझे अभी तक नहीं पता था, लेकिन ऐसा लगता है कि आपको जानकारी प्राप्त करने के लिए कर्नेल मॉड्यूल की आवश्यकता है, जो बाधा हो सकती है।

मुझे लगता है कि हर कोई डब्लूआरटी "मेमोरी यूज" को जानना चाहता है ...
लिनक्स में, एक ही प्रक्रिया का उपयोग करने वाली भौतिक स्मृति की मात्रा को निम्नलिखित श्रेणियों में मोटे तौर पर विभाजित किया जा सकता है।

  • मा अनाम मैप किए गए मेमोरी

    • निजी निजी
      • डीडी == malloc / mmapped ढेर और आवंटित और लिखित स्मृति ढेर
      • .c clean == malloc / mmapped ढेर और आवंटित एक बार आवंटित, लिखित, फिर मुक्त, लेकिन अभी तक पुनः दावा नहीं किया गया
    • साझा किया गया
      • .d dirty == malloc / mmaped ढेर को कॉपी-ऑन-राइट प्राप्त हो सकता है और प्रक्रियाओं के बीच साझा किया जा सकता है (संपादित)
      • .c clean == malloc / mmaped ढेर कॉपी-ऑन-राइट प्राप्त कर सकता है और प्रक्रियाओं के बीच साझा किया जा सकता है (संपादित)
  • एमएन मैप मेमोरी नाम दिया

    • निजी निजी
      • .d dirty == फ़ाइल mmapped लिखित मेमोरी निजी
      • .c clean == मैप किए गए प्रोग्राम / लाइब्रेरी टेक्स्ट निजी मैप किए गए
    • साझा किया गया
      • .d dirty == फ़ाइल mmapped लिखित मेमोरी साझा की गई
      • .c clean == मैप किए गए लाइब्रेरी टेक्स्ट को मैप किया गया

एंड्रॉइड में शोटाप नामक उपयोगिता काफी उपयोगी है

virtual                    shared   shared   private  private
size     RSS      PSS      clean    dirty    clean    dirty    object
-------- -------- -------- -------- -------- -------- -------- ------------------------------
       4        0        0        0        0        0        0 0:00 0                  [vsyscall]
       4        4        0        4        0        0        0                         [vdso]
      88       28       28        0        0        4       24                         [stack]
      12       12       12        0        0        0       12 7909                    /lib/ld-2.11.1.so
      12        4        4        0        0        0        4 89529                   /usr/lib/locale/en_US.utf8/LC_IDENTIFICATION
      28        0        0        0        0        0        0 86661                   /usr/lib/gconv/gconv-modules.cache
       4        0        0        0        0        0        0 87660                   /usr/lib/locale/en_US.utf8/LC_MEASUREMENT
       4        0        0        0        0        0        0 89528                   /usr/lib/locale/en_US.utf8/LC_TELEPHONE
       4        0        0        0        0        0        0 89527                   /usr/lib/locale/en_US.utf8/LC_ADDRESS
       4        0        0        0        0        0        0 87717                   /usr/lib/locale/en_US.utf8/LC_NAME
       4        0        0        0        0        0        0 87873                   /usr/lib/locale/en_US.utf8/LC_PAPER
       4        0        0        0        0        0        0 13879                   /usr/lib/locale/en_US.utf8/LC_MESSAGES/SYS_LC_MESSAGES
       4        0        0        0        0        0        0 89526                   /usr/lib/locale/en_US.utf8/LC_MONETARY
       4        0        0        0        0        0        0 89525                   /usr/lib/locale/en_US.utf8/LC_TIME
       4        0        0        0        0        0        0 11378                   /usr/lib/locale/en_US.utf8/LC_NUMERIC
    1156        8        8        0        0        4        4 11372                   /usr/lib/locale/en_US.utf8/LC_COLLATE
     252        0        0        0        0        0        0 11321                   /usr/lib/locale/en_US.utf8/LC_CTYPE
     128       52        1       52        0        0        0 7909                    /lib/ld-2.11.1.so
    2316       32       11       24        0        0        8 7986                    /lib/libncurses.so.5.7
    2064        8        4        4        0        0        4 7947                    /lib/libdl-2.11.1.so
    3596      472       46      440        0        4       28 7933                    /lib/libc-2.11.1.so
    2084        4        0        4        0        0        0 7995                    /lib/libnss_compat-2.11.1.so
    2152        4        0        4        0        0        0 7993                    /lib/libnsl-2.11.1.so
    2092        0        0        0        0        0        0 8009                    /lib/libnss_nis-2.11.1.so
    2100        0        0        0        0        0        0 7999                    /lib/libnss_files-2.11.1.so
    3752     2736     2736        0        0      864     1872                         [heap]
      24       24       24        0        0        0       24 [anon]
     916      616      131      584        0        0       32                         /bin/bash
-------- -------- -------- -------- -------- -------- -------- ------------------------------
   22816     4004     3005     1116        0      876     2012 TOTAL

Below command line will give you the total memory used by the various process running on the Linux machine in MB

ps -eo size,pid,user,command --sort -size | awk '{ hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }' | awk '{total=total + $1} END {print total}'


Get valgrind. give it your program to run, and it'll tell you plenty about its memory usage.

This would apply only for the case of a program that runs for some time and stops. I don't know if valgrind can get its hands on an already-running process or shouldn't-stop processes such as daemons.


I would suggest that you use atop. You can find everything about it on this page . It is capable of providing all the necessary KPI for your processes and it can also capture to a file.


If you want something quicker than profiling with Valgrind and your kernel is older and you can't use smaps, a ps with the options to show the resident set of the process (with ps -o rss,command ) can give you a quick and reasonable _aproximation_ of the real amount of non-swapped memory being used.


Three more methods to try:

  1. ps aux --sort pmem
    It sorts the output by %MEM .
  2. ps aux | awk '{print $2, $4, $11}' | sort -k2r | head -n 15
    It sorts using pipes.
  3. top -a
    It starts top sorting by %MEM

(Extracted from here )


While this question seems to be about examining currently running processes, I wanted to see the peak memory used by an application from start to finish. Besides valgrind, you can use tstime , which is much simpler. It measures the "highwater" memory usage (RSS and virtual). From this answer .


#!/bin/ksh
#
# Returns total memory used by process $1 in kb.
#
# See /proc/NNNN/smaps if you want to do something
# more interesting.
#

IFS=$'\n'

for line in $(</proc/$1/smaps)
do
   [[ $line =~ ^Size:\s+(\S+) ]] && ((kb += ${.sh.match[1]}))
done

print $kb




process