كيفية قياس الاستخدام الفعلي للذاكرة لتطبيق أو عملية؟
سؤال
تمت تغطية هذا السؤال هنا في تفاصيل عظيمة.
كيف يمكنك قياس استخدام الذاكرة لتطبيق أو عملية في Linux؟
من مقال المدونة فهم استخدام الذاكرة على نظام التشغيل Linux, ps
ليست أداة دقيقة لاستخدامها لهذا الغرض.
لماذا
ps
خطأ"اعتمادًا على الطريقة التي تنظر بها إلى الأمر،
ps
لا يتم الإبلاغ عن استخدام الذاكرة الحقيقي للعمليات.ما تفعله حقًا هو إظهار مقدار الذاكرة الحقيقية التي ستستهلكها كل عملية لو كانت العملية الوحيدة قيد التشغيل.بالطبع، يحتوي جهاز Linux النموذجي على عشرات العمليات التي يتم تشغيلها في أي وقت، مما يعني أن أرقام VSZ وRSS التي يتم الإبلاغ عنها بواسطةps
يكاد يكون من المؤكد خطأ.
المحلول
مع ps
أو الأدوات المشابهة، فلن تحصل إلا على مقدار صفحات الذاكرة المخصصة لهذه العملية.هذا الرقم صحيح ولكن:
لا يعكس مقدار الذاكرة الفعلي الذي يستخدمه التطبيق، فقط مقدار الذاكرة المحجوزة له
يمكن أن تكون مضللة إذا تمت مشاركة الصفحات، على سبيل المثال عن طريق عدة سلاسل رسائل أو عن طريق استخدام المكتبات المرتبطة ديناميكيًا
إذا كنت تريد حقًا معرفة مقدار الذاكرة التي يستخدمها تطبيقك بالفعل، فأنت بحاجة إلى تشغيله ضمن ملف التعريف.على سبيل المثال، valgrind
يمكن أن يوفر لك معلومات حول مقدار الذاكرة المستخدمة، والأهم من ذلك، حول تسرب الذاكرة المحتمل في برنامجك.يُطلق على أداة ملف تعريف الكومة الخاصة بـ valgrind اسم "massif":
Massif هو منشئ ملفات التعريف الكومة.يقوم بتنفيذ ملفات تعريف الكومة التفصيلية عن طريق التقاط لقطات منتظمة لكومة البرنامج.وينتج رسمًا بيانيًا يوضح استخدام الكومة بمرور الوقت، بما في ذلك معلومات حول أجزاء البرنامج المسؤولة عن معظم عمليات تخصيص الذاكرة.يتم استكمال الرسم البياني بنص أو ملف HTML يتضمن المزيد من المعلومات لتحديد المكان الذي يتم تخصيص أكبر قدر من الذاكرة فيه.يقوم Massif بتشغيل البرامج بمعدل 20 مرة أبطأ من المعتاد.
كما هو موضح في وثائق فالجريند, ، تحتاج إلى تشغيل البرنامج من خلال valgrind:
valgrind --tool=massif <executable> <arguments>
يكتب Massif تفريغًا من لقطات استخدام الذاكرة (على سبيل المثال. massif.out.12345
).توفر هذه (1) جدولًا زمنيًا لاستخدام الذاكرة، (2) لكل لقطة، سجلاً بالمكان الذي تم تخصيصه في ذاكرة البرنامج الخاص بك.أداة رسومية رائعة لتحليل هذه الملفات هي متخيل الكتلة.لكنني وجدت ms_print
, ، وهي أداة نصية بسيطة يتم شحنها مع valgrind، لتكون ذات فائدة كبيرة بالفعل.
للعثور على تسرب الذاكرة، استخدم (الافتراضي) memcheck
أداة فالجريند.
نصائح أخرى
جرب ال com.pmap يأمر:
sudo pmap -x <process pid>
من الصعب تحديد ذلك على وجه اليقين، ولكن هناك شيئان "مقربان" يمكن أن يساعدا.
$ ps aux
سيعطيك الحجم الافتراضي (VSZ)
يمكنك أيضًا الحصول على إحصائيات تفصيلية من نظام الملفات /proc بالانتقال إلى /proc/$pid/status
الأهم هو 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
في الإصدارات الأخيرة من Linux، استخدم خرائط النظام الفرعي.على سبيل المثال، بالنسبة لعملية بمعرف PID 1234:
cat /proc/1234/smaps
سيخبرك بالضبط مقدار الذاكرة التي يستخدمها في ذلك الوقت.والأهم من ذلك، أنه سيتم تقسيم الذاكرة إلى خاصة ومشتركة، حتى تتمكن من معرفة مقدار الذاكرة لديك مثال من البرنامج قيد الاستخدام، دون تضمين الذاكرة المشتركة بين مثيلات متعددة من البرنامج.
لا توجد طريقة سهلة لحساب هذا.لكن بعض الأشخاص حاولوا الحصول على بعض الإجابات الجيدة:
يستخدم com.smem, ، وهو بديل ل ملاحظة الذي يحسب USS وPSS لكل عملية.ما تريده هو على الأرجح PSS.
يو اس اس - حجم المجموعة الفريد.هذا هو مقدار الذاكرة غير المشتركة الفريدة لهذه العملية (فكر في الأمر على أنه ش ل فريد ذاكرة).لا يتضمن الذاكرة المشتركة.هكذا سوف تحت- قم بالإبلاغ عن مقدار الذاكرة التي تستخدمها العملية، ولكنه مفيد عندما تريد تجاهل الذاكرة المشتركة.
بي.اس.اس - حجم المجموعة النسبي.هذا ما تريده انت.فهو يجمع الذاكرة الفريدة (USS)، إلى جانب نسبة من ذاكرتها المشتركة مقسومة على عدد العمليات الأخرى التي تتقاسم تلك الذاكرة.وبالتالي سيعطيك تمثيلًا دقيقًا لمقدار الذاكرة الفعلية المستخدمة لكل عملية - مع تمثيل الذاكرة المشتركة حقًا على أنها مشتركة.فكر في ص يجري ل بدني ذاكرة.
كيف يقارن هذا بـ RSS كما ذكرت ملاحظة وغيرها من المرافق:
- آر إس إس - حجم المجموعة المقيمة.هذا هو مقدار الذاكرة المشتركة بالإضافة إلى الذاكرة غير المشتركة التي تستخدمها كل عملية.إذا كانت هناك أي عمليات تشترك في الذاكرة، فسيتم ذلك زيادة- قم بالإبلاغ عن مقدار الذاكرة المستخدمة بالفعل، لأنه سيتم حساب نفس الذاكرة المشتركة أكثر من مرة - وستظهر مرة أخرى في كل عملية أخرى تشترك في نفس الذاكرة.هكذا هو الحال تماما لا يمكن الاعتماد عليها، خاصة عندما تحتوي العمليات ذات الذاكرة العالية على الكثير من التشعبات - وهو أمر شائع في الخادم، مع أشياء مثل عمليات Apache أو PHP(fastcgi/FPM).
يلاحظ:يمكن لـ smem أيضًا (اختياريًا) إخراج الرسوم البيانية مثل المخططات الدائرية وما شابه.المنظمة البحرية الدولية (IMO) لا تحتاج إلى أي من ذلك.إذا كنت تريد استخدامه فقط من سطر الأوامر كما قد تستخدم ps -A v، فلن تحتاج إلى تثبيت التبعية الموصى بها من python-matplotlib.
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 "" }' |\
cut -d "" -f2 | cut -d "-" -f1
استخدم هذا كجذر ويمكنك الحصول على إخراج واضح لاستخدام الذاكرة في كل عملية.
مثال الإخراج:
0.00 Mb COMMAND
1288.57 Mb /usr/lib/firefox
821.68 Mb /usr/lib/chromium/chromium
762.82 Mb /usr/lib/chromium/chromium
588.36 Mb /usr/sbin/mysqld
547.55 Mb /usr/lib/chromium/chromium
523.92 Mb /usr/lib/tracker/tracker
476.59 Mb /usr/lib/chromium/chromium
446.41 Mb /usr/bin/gnome
421.62 Mb /usr/sbin/libvirtd
405.11 Mb /usr/lib/chromium/chromium
302.60 Mb /usr/lib/chromium/chromium
291.46 Mb /usr/lib/chromium/chromium
284.56 Mb /usr/lib/chromium/chromium
238.93 Mb /usr/lib/tracker/tracker
223.21 Mb /usr/lib/chromium/chromium
197.99 Mb /usr/lib/chromium/chromium
194.07 Mb conky
191.92 Mb /usr/lib/chromium/chromium
190.72 Mb /usr/bin/mongod
169.06 Mb /usr/lib/chromium/chromium
155.11 Mb /usr/bin/gnome
136.02 Mb /usr/lib/chromium/chromium
125.98 Mb /usr/lib/chromium/chromium
103.98 Mb /usr/lib/chromium/chromium
93.22 Mb /usr/lib/tracker/tracker
89.21 Mb /usr/lib/gnome
80.61 Mb /usr/bin/gnome
77.73 Mb /usr/lib/evolution/evolution
76.09 Mb /usr/lib/evolution/evolution
72.21 Mb /usr/lib/gnome
69.40 Mb /usr/lib/evolution/evolution
68.84 Mb nautilus
68.08 Mb zeitgeist
60.97 Mb /usr/lib/tracker/tracker
59.65 Mb /usr/lib/evolution/evolution
57.68 Mb apt
55.23 Mb /usr/lib/gnome
53.61 Mb /usr/lib/evolution/evolution
53.07 Mb /usr/lib/gnome
52.83 Mb /usr/lib/gnome
51.02 Mb /usr/lib/udisks2/udisksd
50.77 Mb /usr/lib/evolution/evolution
50.53 Mb /usr/lib/gnome
50.45 Mb /usr/lib/gvfs/gvfs
50.36 Mb /usr/lib/packagekit/packagekitd
50.14 Mb /usr/lib/gvfs/gvfs
48.95 Mb /usr/bin/Xwayland :1024
46.21 Mb /usr/bin/gnome
42.43 Mb /usr/bin/zeitgeist
42.29 Mb /usr/lib/gnome
41.97 Mb /usr/lib/gnome
41.64 Mb /usr/lib/gvfs/gvfsd
41.63 Mb /usr/lib/gvfs/gvfsd
41.55 Mb /usr/lib/gvfs/gvfsd
41.48 Mb /usr/lib/gvfs/gvfsd
39.87 Mb /usr/bin/python /usr/bin/chrome
37.45 Mb /usr/lib/xorg/Xorg vt2
36.62 Mb /usr/sbin/NetworkManager
35.63 Mb /usr/lib/caribou/caribou
34.79 Mb /usr/lib/tracker/tracker
33.88 Mb /usr/sbin/ModemManager
33.77 Mb /usr/lib/gnome
33.61 Mb /usr/lib/upower/upowerd
33.53 Mb /usr/sbin/gdm3
33.37 Mb /usr/lib/gvfs/gvfsd
33.36 Mb /usr/lib/gvfs/gvfs
33.23 Mb /usr/lib/gvfs/gvfs
33.15 Mb /usr/lib/at
33.15 Mb /usr/lib/at
30.03 Mb /usr/lib/colord/colord
29.62 Mb /usr/lib/apt/methods/https
28.06 Mb /usr/lib/zeitgeist/zeitgeist
27.29 Mb /usr/lib/policykit
25.55 Mb /usr/lib/gvfs/gvfs
25.55 Mb /usr/lib/gvfs/gvfs
25.23 Mb /usr/lib/accountsservice/accounts
25.18 Mb /usr/lib/gvfs/gvfsd
25.15 Mb /usr/lib/gvfs/gvfs
25.15 Mb /usr/lib/gvfs/gvfs
25.12 Mb /usr/lib/gvfs/gvfs
25.10 Mb /usr/lib/gnome
25.10 Mb /usr/lib/gnome
25.07 Mb /usr/lib/gvfs/gvfsd
24.99 Mb /usr/lib/gvfs/gvfs
23.26 Mb /usr/lib/chromium/chromium
22.09 Mb /usr/bin/pulseaudio
19.01 Mb /usr/bin/pulseaudio
18.62 Mb (sd
18.46 Mb (sd
18.30 Mb /sbin/init
18.17 Mb /usr/sbin/rsyslogd
17.50 Mb gdm
17.42 Mb gdm
17.09 Mb /usr/lib/dconf/dconf
17.09 Mb /usr/lib/at
17.06 Mb /usr/lib/gvfs/gvfsd
16.98 Mb /usr/lib/at
16.91 Mb /usr/lib/gdm3/gdm
16.86 Mb /usr/lib/gvfs/gvfsd
16.86 Mb /usr/lib/gdm3/gdm
16.85 Mb /usr/lib/dconf/dconf
16.85 Mb /usr/lib/dconf/dconf
16.73 Mb /usr/lib/rtkit/rtkit
16.69 Mb /lib/systemd/systemd
13.13 Mb /usr/lib/chromium/chromium
13.13 Mb /usr/lib/chromium/chromium
10.92 Mb anydesk
8.54 Mb /sbin/lvmetad
7.43 Mb /usr/sbin/apache2
6.82 Mb /usr/sbin/apache2
6.77 Mb /usr/sbin/apache2
6.73 Mb /usr/sbin/apache2
6.66 Mb /usr/sbin/apache2
6.64 Mb /usr/sbin/apache2
6.63 Mb /usr/sbin/apache2
6.62 Mb /usr/sbin/apache2
6.51 Mb /usr/sbin/apache2
6.25 Mb /usr/sbin/apache2
6.22 Mb /usr/sbin/apache2
3.92 Mb bash
3.14 Mb bash
2.97 Mb bash
2.95 Mb bash
2.93 Mb bash
2.91 Mb bash
2.86 Mb bash
2.86 Mb bash
2.86 Mb bash
2.84 Mb bash
2.84 Mb bash
2.45 Mb /lib/systemd/systemd
2.30 Mb (sd
2.28 Mb /usr/bin/dbus
1.84 Mb /usr/bin/dbus
1.46 Mb ps
1.21 Mb openvpn hackthebox.ovpn
1.16 Mb /sbin/dhclient
1.16 Mb /sbin/dhclient
1.09 Mb /lib/systemd/systemd
0.98 Mb /sbin/mount.ntfs /dev/sda3 /media/n0bit4/Data
0.97 Mb /lib/systemd/systemd
0.96 Mb /lib/systemd/systemd
0.89 Mb /usr/sbin/smartd
0.77 Mb /usr/bin/dbus
0.76 Mb su
0.76 Mb su
0.76 Mb su
0.76 Mb su
0.76 Mb su
0.76 Mb su
0.75 Mb sudo su
0.75 Mb sudo su
0.75 Mb sudo su
0.75 Mb sudo su
0.75 Mb sudo su
0.75 Mb sudo su
0.74 Mb /usr/bin/dbus
0.71 Mb /usr/lib/apt/methods/http
0.68 Mb /bin/bash /usr/bin/mysqld_safe
0.68 Mb /sbin/wpa_supplicant
0.66 Mb /usr/bin/dbus
0.61 Mb /lib/systemd/systemd
0.54 Mb /usr/bin/dbus
0.46 Mb /usr/sbin/cron
0.45 Mb /usr/sbin/irqbalance
0.43 Mb logger
0.41 Mb awk { hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }
0.40 Mb /usr/bin/ssh
0.34 Mb /usr/lib/chromium/chrome
0.32 Mb cut
0.32 Mb cut
0.00 Mb [kthreadd]
0.00 Mb [ksoftirqd/0]
0.00 Mb [kworker/0:0H]
0.00 Mb [rcu_sched]
0.00 Mb [rcu_bh]
0.00 Mb [migration/0]
0.00 Mb [lru
0.00 Mb [watchdog/0]
0.00 Mb [cpuhp/0]
0.00 Mb [cpuhp/1]
0.00 Mb [watchdog/1]
0.00 Mb [migration/1]
0.00 Mb [ksoftirqd/1]
0.00 Mb [kworker/1:0H]
0.00 Mb [cpuhp/2]
0.00 Mb [watchdog/2]
0.00 Mb [migration/2]
0.00 Mb [ksoftirqd/2]
0.00 Mb [kworker/2:0H]
0.00 Mb [cpuhp/3]
0.00 Mb [watchdog/3]
0.00 Mb [migration/3]
0.00 Mb [ksoftirqd/3]
0.00 Mb [kworker/3:0H]
0.00 Mb [kdevtmpfs]
0.00 Mb [netns]
0.00 Mb [khungtaskd]
0.00 Mb [oom_reaper]
0.00 Mb [writeback]
0.00 Mb [kcompactd0]
0.00 Mb [ksmd]
0.00 Mb [khugepaged]
0.00 Mb [crypto]
0.00 Mb [kintegrityd]
0.00 Mb [bioset]
0.00 Mb [kblockd]
0.00 Mb [devfreq_wq]
0.00 Mb [watchdogd]
0.00 Mb [kswapd0]
0.00 Mb [vmstat]
0.00 Mb [kthrotld]
0.00 Mb [ipv6_addrconf]
0.00 Mb [acpi_thermal_pm]
0.00 Mb [ata_sff]
0.00 Mb [scsi_eh_0]
0.00 Mb [scsi_tmf_0]
0.00 Mb [scsi_eh_1]
0.00 Mb [scsi_tmf_1]
0.00 Mb [scsi_eh_2]
0.00 Mb [scsi_tmf_2]
0.00 Mb [scsi_eh_3]
0.00 Mb [scsi_tmf_3]
0.00 Mb [scsi_eh_4]
0.00 Mb [scsi_tmf_4]
0.00 Mb [scsi_eh_5]
0.00 Mb [scsi_tmf_5]
0.00 Mb [bioset]
0.00 Mb [kworker/1:1H]
0.00 Mb [kworker/3:1H]
0.00 Mb [kworker/0:1H]
0.00 Mb [kdmflush]
0.00 Mb [bioset]
0.00 Mb [kdmflush]
0.00 Mb [bioset]
0.00 Mb [jbd2/sda5
0.00 Mb [ext4
0.00 Mb [kworker/2:1H]
0.00 Mb [kauditd]
0.00 Mb [bioset]
0.00 Mb [drbd
0.00 Mb [irq/27
0.00 Mb [i915/signal:0]
0.00 Mb [i915/signal:1]
0.00 Mb [i915/signal:2]
0.00 Mb [ttm_swap]
0.00 Mb [cfg80211]
0.00 Mb [kworker/u17:0]
0.00 Mb [hci0]
0.00 Mb [hci0]
0.00 Mb [kworker/u17:1]
0.00 Mb [iprt
0.00 Mb [iprt
0.00 Mb [kworker/1:0]
0.00 Mb [kworker/3:0]
0.00 Mb [kworker/0:0]
0.00 Mb [kworker/2:0]
0.00 Mb [kworker/u16:0]
0.00 Mb [kworker/u16:2]
0.00 Mb [kworker/3:2]
0.00 Mb [kworker/2:1]
0.00 Mb [kworker/1:2]
0.00 Mb [kworker/0:2]
0.00 Mb [kworker/2:2]
0.00 Mb [kworker/0:1]
0.00 Mb [scsi_eh_6]
0.00 Mb [scsi_tmf_6]
0.00 Mb [usb
0.00 Mb [bioset]
0.00 Mb [kworker/3:1]
0.00 Mb [kworker/u16:1]
ماذا عن time
?
ليس سحق مدمج time
ولكن الذي يمكنك العثور عليه which time
, ، على سبيل المثال /usr/bin/time
وإليك ما يغطيه، بشكل بسيط ls
:
$ /usr/bin/time --verbose ls
(...)
Command being timed: "ls"
User time (seconds): 0.00
System time (seconds): 0.00
Percent of CPU this job got: 0%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 2372
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 1
Minor (reclaiming a frame) page faults: 121
Voluntary context switches: 2
Involuntary context switches: 9
Swaps: 0
File system inputs: 256
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0
وهذا ملخص ممتاز للأدوات والمشكلات: رابط archive.org
سأقتبسه، حتى يتمكن المزيد من المطورين من قراءته بالفعل.
إذا كنت ترغب في تحليل استخدام الذاكرة للنظام بأكمله أو تحليل استخدام الذاكرة لتطبيق واحد بشكل شامل (وليس فقط استخدام الكومة)، فاستخدم com.exmap.بالنسبة لتحليل النظام بالكامل، ابحث عن العمليات ذات الاستخدام الأكثر فعالية، فهي تستهلك أكبر قدر من الذاكرة في الممارسة العملية، وتبحث عن العمليات ذات أعلى استخدام قابل للكتابة، وتنشئ معظم البيانات (وبالتالي ربما تتسرب أو تكون غير فعالة جدًا في استخدام البيانات).حدد هذا التطبيق وقم بتحليل تعييناته في عرض القائمة الثاني.راجع قسم exmap لمزيد من التفاصيل.أيضا استخدام com.xrestop للتحقق من الاستخدام العالي لموارد X، خاصة إذا كانت عملية خادم X تستهلك قدرًا كبيرًا من الذاكرة.راجع قسم xrestop للحصول على التفاصيل.
إذا كنت ترغب في الكشف عن التسريبات، استخدم valgrind أو ربما kmtrace.
إذا كنت تريد تحليل استخدام الكومة (malloc وما إلى ذلك) لأحد التطبيقات، فقم بتشغيله com.memprof أو مع kmtrace, قم بإنشاء ملف تعريف للتطبيق وابحث في شجرة استدعاء الوظائف للحصول على أكبر التخصيصات.انظر أقسامهم لمزيد من التفاصيل.
بجانب الحلول المدرجة في إجاباتك، يمكنك استخدام أمر Linux "أعلى"؛فهو يوفر عرضًا ديناميكيًا في الوقت الفعلي للنظام قيد التشغيل، ويعطي استخدام وحدة المعالجة المركزية والذاكرة للنظام بأكمله بالإضافة إلى كل برنامج بالنسبة المئوية:
top
للتصفية حسب معرف البرنامج:
top -p <PID>
للتصفية حسب اسم البرنامج:
top | grep <PROCESS NAME>
يوفر "الأعلى" أيضًا بعض الحقول مثل:
VIRT - الصورة الافتراضية (كيلو بايت): إجمالي مقدار الذاكرة الظاهرية التي تستخدمها المهمة
RES - حجم المقيم (كيلو بايت):الذاكرة الفعلية غير القابلة للتبديل التي استخدمتها المهمة؛الدقة = الكود + البيانات.
البيانات - حجم البيانات + المكدس (كيلو بايت):مقدار الذاكرة الفعلية المخصصة لغير التعليمات البرمجية القابلة للتنفيذ، والمعروفة أيضًا بحجم "مجموعة البيانات المقيمة" أو DRS.
SHR - حجم الذاكرة المشتركة (كيلو بايت):مقدار الذاكرة المشتركة التي تستخدمها المهمة.إنه يعكس ببساطة الذاكرة التي يمكن مشاركتها مع العمليات الأخرى.
مرجع هنا.
لا توجد إجابة واحدة لهذا لأنه لا يمكنك تحديد مقدار الذاكرة التي تستخدمها العملية بدقة.تستخدم معظم العمليات في نظام Linux المكتبات المشتركة.على سبيل المثال، لنفترض أنك تريد حساب استخدام الذاكرة لعملية 'ls'.هل تحسب فقط الذاكرة التي يستخدمها الملف القابل للتنفيذ "ls" (إذا كان بإمكانك عزلها)؟ماذا عن ليبك؟أو كل هذه libs الأخرى المطلوبة لتشغيل 'ls'؟
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/status قد يمنحك معلومات كافية عن استخدام الذاكرة في وقت واحد.من ناحية أخرى، سيمنحك valgrind ملف تعريف أفضل لاستخدام الذاكرة طوال عمر البرنامج
إذا كان الكود الخاص بك مكتوبًا بلغة C أو C++، فقد تتمكن من استخدامه getrusage()
والذي يُرجع لك إحصائيات مختلفة حول استخدام الذاكرة والوقت للعملية الخاصة بك.
على الرغم من ذلك، لا تدعم كافة الأنظمة الأساسية هذا وستُرجع 0 قيمًا لخيارات استخدام الذاكرة.
بدلا من ذلك يمكنك إلقاء نظرة على الملف الظاهري الذي تم إنشاؤه فيه /proc/[pid]/statm
(أين [pid]
يتم استبداله بمعرف العملية الخاص بك.يمكنك الحصول على هذا من getpid()
).
سيبدو هذا الملف كملف نصي يحتوي على 7 أعداد صحيحة.ربما تكون مهتمًا جدًا بالرقمين الأول (جميع استخدامات الذاكرة) والسادس (استخدام ذاكرة البيانات) في هذا الملف.
فالجريند يمكن أن تظهر معلومات مفصلة ولكن ذلك أبطئ التطبيق المستهدف بشكل ملحوظ، وفي أغلب الأحيان يغير سلوك التطبيق.
خريطة كان شيئًا لم أكن أعرفه بعد، ولكن يبدو أنك بحاجة إلى وحدة النواة للحصول على المعلومات، والتي يمكن أن تشكل عائقا.
أفترض أن ما يريد الجميع معرفته "استخدام الذاكرة" هو ما يلي ...
في نظام التشغيل Linux، يمكن تقسيم مقدار الذاكرة الفعلية التي قد تستخدمها عملية واحدة تقريبًا إلى الفئات التالية.
M. ذاكرة مجهولة معينة
- .ع خاص
- .d قذر == الكومة والمكدس malloc/mmapped الذاكرة المخصصة والمكتوبة
- .c clean == malloc/mmapped الكومة والذاكرة المكدسة بمجرد تخصيصها وكتابتها ثم تحريرها، ولكن لم يتم استعادتها بعد
- .s المشتركة
- .د القذرة == يمكن أن تحصل الكومة malloc/mmaped على نسخة عند الكتابة ومشاركتها بين العمليات (تحرير)
- .ج نظيفة == يمكن أن تحصل الكومة malloc/mmaped على نسخة عند الكتابة ومشاركتها بين العمليات (تحرير)
- .ع خاص
M.n اسمه الذاكرة المعينة
- .ع خاص
- .d القذرة == ملف mmapped الذاكرة المكتوبة الخاصة
- .c نظيف == تم تعيين نص البرنامج/المكتبة بشكل خاص
- .s المشتركة
- .d القذرة == ملف الذاكرة المكتوبة mmapped المشتركة
- .c clean == نص المكتبة المعينة المشتركة المعينة
- .ع خاص
الأداة المساعدة المضمنة في Android تسمى عرض الخريطة مفيد جدًا
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
أنا استخدم htop
;إنه برنامج وحدة تحكم جيد جدًا يشبه Windows Task Manager.
يعد Valgrind رائعًا إذا كان لديك الوقت لتشغيله. valgrind --tool=massif
هو الحل الصحيح.
ومع ذلك، فقد بدأت في تشغيل أمثلة أكبر، ولم يعد استخدام valgrind عمليًا.هل هناك طريقة لمعرفة الحد الأقصى لاستخدام الذاكرة (حجم الصفحة المعيارية والصفحات المشتركة) للبرنامج؟
على نظام يونكس حقيقي، /usr/bin/time -v
يعمل.لكن هذا يحدث في Linux لا عمل.
ثلاث طرق أخرى للتجربة:
ps aux --sort pmem
يقوم بفرز الإخراج حسب%MEM
.ps aux | awk '{print $2, $4, $11}' | sort -k2r | head -n 15
يتم الفرز باستخدام الأنابيب.top -a
يبدأ الفرز العلوي حسب%MEM
(مستخرج من هنا)
#!/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
الاختبار الجيد لاستخدام "العالم الحقيقي" هو فتح التطبيق، ثم تشغيله vmstat -s
وتحقق من إحصائية "الذاكرة النشطة".أغلق التطبيق وانتظر بضع ثوان ثم قم بتشغيله vmstat -s
مرة أخرى.ومع ذلك، فمن الواضح أن الكثير من الذاكرة النشطة التي تم تحريرها كانت قيد الاستخدام بواسطة التطبيق.
إذا كانت العملية لا تستهلك قدرًا كبيرًا من الذاكرة (إما لأنك تتوقع أن يحدث هذا، أو لأن بعض الأوامر الأخرى أعطت هذه الإشارة الأولية)، ويمكن أن تتحمل العملية التوقف لفترة قصيرة من الوقت، فيمكنك محاولة استخدم الأمر gcore.
gcore <pid>
تحقق من حجم الملف الأساسي الذي تم إنشاؤه للحصول على فكرة جيدة عن مقدار الذاكرة التي تستخدمها عملية معينة.
لن يعمل هذا جيدًا إذا كانت العملية تستخدم مئات الميجات أو العربات، حيث قد يستغرق إنشاء الجيل الأساسي عدة ثوانٍ أو دقائق اعتمادًا على أداء الإدخال/الإخراج.أثناء الإنشاء الأساسي، يتم إيقاف العملية (أو "تجميدها") لمنع حدوث تغييرات في الذاكرة.لذا كن حذرا.
تأكد أيضًا من أن نقطة التثبيت حيث يتم إنشاء المركز بها مساحة كبيرة على القرص وأن النظام لن يتفاعل بشكل سلبي مع الملف الأساسي الذي يتم إنشاؤه في هذا الدليل المحدد.
سيعطيك سطر الأوامر أدناه إجمالي الذاكرة المستخدمة في العمليات المختلفة التي يتم تشغيلها على جهاز Linux بالميجابايت
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}'
أنا أستخدم Arch Linux وهناك هذه الحزمة الرائعة التي تسمى ps_mem
ps_mem -p <pid>
إخراج المثال
$ ps_mem -S -p $(pgrep firefox)
Private + Shared = RAM used Swap used Program
355.0 MiB + 38.7 MiB = 393.7 MiB 35.9 MiB firefox
---------------------------------------------
393.7 MiB 35.9 MiB
=============================================
احصل على فالجريند.أعطه برنامجك ليعمل، وسيخبرك بالكثير عن استخدام الذاكرة.
ينطبق هذا فقط على حالة البرنامج الذي يعمل لبعض الوقت ويتوقف.لا أعرف ما إذا كان بإمكان valgrind وضع يديه على عملية قيد التشغيل بالفعل أو لا ينبغي له إيقاف العمليات مثل الشياطين.
يحرر: يعمل هذا بشكل جيد بنسبة 100% فقط عند زيادة استهلاك الذاكرة
إذا كنت ترغب في مراقبة استخدام الذاكرة من خلال عملية معينة (أو مجموعة من الاسم الشائع للمشاركة المعالجة، على سبيل المثال. google-chrome
, ، يمكنك استخدام نص bash الخاص بي:
while true; do ps aux | awk ‚{print $5, $11}’ | grep chrome | sort -n > /tmp/a.txt; sleep 1; diff /tmp/{b,a}.txt; mv /tmp/{a,b}.txt; done;
سيبحث هذا باستمرار عن التغييرات ويطبعها.
إذا كنت تريد شيئًا أسرع من التوصيف باستخدام Valgrind وكانت نواة جهازك أقدم ولا يمكنك استخدام smaps، فستجد ملاحظة مع خيارات لإظهار المجموعة المقيمة للعملية (مع ps -o rss,command
) يمكن أن يوفر لك سريعة ومعقولة _aproximation_
من المقدار الحقيقي للذاكرة غير القابلة للتبديل المستخدمة.
أود أن أقترح عليك استخدام فوق.يمكنك أن تجد كل شيء عن ذلك على هذه الصفحة.إنه قادر على توفير جميع مؤشرات الأداء الرئيسية الضرورية لعملياتك ويمكنه أيضًا التقاطها في ملف.
تحقق من البرنامج النصي Shell للتحقق استخدام الذاكرة من خلال التطبيق في لينكس.متاح أيضا على جيثب وفي نسخة بدون لصق وقبل الميلاد.
بينما يبدو أن هذا السؤال يتعلق بفحص العمليات الجارية حاليًا، إلا أنني أردت رؤية الحد الأقصى للذاكرة التي يستخدمها التطبيق من البداية إلى النهاية.بالإضافة إلى valgrind، يمكنك استخدام com.tstime, ، وهو أبسط بكثير.فهو يقيس استخدام الذاكرة "المياه العالية" (RSS والظاهرية).من هذه الإجابة.
استخدم المدمج فيمراقب النظامأداة واجهة المستخدم الرسومية متوفرة في أوبونتو
بناء على الإجابة على ذات الصلة سؤال.
يمكنك استخدام SNMP للحصول على الذاكرة واستخدام وحدة المعالجة المركزية لعملية ما في جهاز معين في الشبكة :)
متطلبات:
- يجب أن يكون جهاز snmp مثبتًا قيد التشغيل ويعمل على الجهاز الذي يقوم بتشغيل العملية
- يجب تكوين snmp لقبول الطلبات من حيث سيتم تشغيل البرنامج النصي أدناه (قد يتم تكوينه في snmpd.conf)
- يجب أن تعرف معرف العملية (pid) للعملية التي تريد مراقبتها
ملحوظات:
المضيف-الموارد-MIB::hrSWRunPerfCPU هو عدد السنتي ثانية من إجمالي موارد وحدة المعالجة المركزية للنظام التي تستهلكها هذه العملية.لاحظ أنه في نظام متعدد المعالجات، قد تزيد هذه القيمة بأكثر من سنتي ثانية واحدة في سنتي ثانية واحدة من الوقت الحقيقي (ساعة الحائط).
المضيف-الموارد-MIB::hrSWRunPerfMem هو إجمالي مقدار ذاكرة النظام الحقيقية المخصصة لهذه العملية.
**
البرنامج النصي لمراقبة العملية:
**
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