يختلف استخدام الذاكرة الذي أبلغ عنه Guppy من أمر PS
-
20-09-2019 - |
سؤال
أنا أقوم بتوصيف الخادم الملتوي. يستخدم ذاكرة أكثر بكثير مما كنت أتوقع. استخدام الذاكرة ينمو بمرور الوقت.
ps -o pid,rss,vsz,sz,size,command
PID RSS VSZ SZ SZ COMMAND
7697 70856 102176 25544 88320 twistd -y broadcast.tac
كما ترون تكاليف 102176 كيلو بايت, ، يسمى، 99.78125 ميغا ح. وأنا أستخدم Guppy من فتحة الملتوية لمشاهدة ملف تعريف استخدام الذاكرة.
>>> hp.heap()
Partition of a set of 120537 objects. Total size = 10096636 bytes.
Index Count % Size % Cumulative % Kind (class / dict of class)
0 61145 51 5309736 53 5309736 53 str
1 27139 23 1031596 10 6341332 63 tuple
2 2138 2 541328 5 6882660 68 dict (no owner)
3 7190 6 488920 5 7371580 73 types.CodeType
4 325 0 436264 4 7807844 77 dict of module
5 7272 6 407232 4 8215076 81 function
6 574 0 305776 3 8520852 84 dict of class
7 605 1 263432 3 8784284 87 type
8 602 0 237200 2 9021484 89 dict of type
9 303 0 157560 2 9179044 91 dict of zope.interface.interface.Method
<384 more rows. Type e.g. '_.more' to view.>
همهمة ... يبدو أن هناك شيئًا خاطئًا. يوضح Guppy أن الاستخدام الكلي للذاكرة هو 10096636 بايت ، أي 9859.996 كيلو بايت أو 9.628 MBS.
هذا فرق كبير. ما هو الخطأ هذه النتيجة الغريبة؟ ما الخطأ الذي افعله؟
تحديث:كتبت نص شاشة الليلة الماضية. يسجل استخدام الذاكرة وعدد المستخدمين عبر الإنترنت. إنه خادم راديو ، حتى تتمكن من رؤية وجود أجهزة راديو ومستمعين إجماليين. هنا هو الشكل الذي أنشأته بواسطة Matplotlib.
شيء غريب. في بعض الأحيان يكون استخدام الذاكرة المطبوع بواسطة PS منخفضًا جدًا ، مثل هذا
2010-01-15 00:46:05,139 INFO 4 4 17904 36732 9183 25944
2010-01-15 00:47:03,967 INFO 4 4 17916 36732 9183 25944
2010-01-15 00:48:04,373 INFO 4 4 17916 36732 9183 25944
2010-01-15 00:49:04,379 INFO 4 4 17916 36732 9183 25944
2010-01-15 00:50:02,989 INFO 4 4 3700 5256 1314 2260
ما هو سبب القيمة السوبر لاستخدام الذاكرة؟ والأكثر من ذلك ، حتى أنه لا يوجد أجهزة الراديو عبر الإنترنت ، ولا مستمعين ، لا يزال استخدام الذاكرة مرتفعًا.
المحلول
ربما بسبب تبادل/حجز الذاكرة ، بناءً على تعريف PS:
RSS: resident set size, the non-swapped physical memory
that a task has used (in kiloBytes).
VSZ: virtual memory usage of entire process.
vm_lib + vm_exe + vm_data + vm_stack
يمكن أن تكون مربكة بعض الشيء ، يمكن رؤية 4 مقاييس مختلفة الحجم مع:
# ps -eo pid,vsz,rss,sz,size,cmd|egrep python
PID VSZ RSS SZ SZ CMD
23801 4920 2896 1230 1100 python
يتضمن الحجم الافتراضي ذاكرة مخصصة للعملية وعدم استخدامها ، وحجم جميع المكتبات المشتركة التي تم تحميلها ، والصفحات التي يتم تبديلها ، والكتل التي تم تحريرها بالفعل من خلال عمليتك ، لذلك قد تكون أكبر بكثير من الحجم من جميع الأشياء الحية في بيثون.
بعض الأدوات الإضافية للتحقيق في أداء الذاكرة:
Heapy (جزء من Guppy ، الذي تستخدمه):http://guppy-pe.sourceforge.net/
Python Memory Vaditatorhttp://www.softwareverify.com/python/memory/index.html
Pysizerhttp://pysizer.8325.org/
دليل جيد على تعقب تسرب الذاكرة في Python باستخدام PDB و Objgraph:
http://www.lshift.net/blog/2008/11/14/tracing-python-memory-leaks
نصائح أخرى
كما هو موضح فوق حجم RSS هو أكثر ما تهتم به هنا. يتضمن الحجم "الظاهري" مكتبات تم تعيينها ، والتي ربما لا ترغب في الاعتماد عليها.
لقد مر وقت منذ أن استخدمت Heapy ، لكنني متأكد تمامًا من أن الإحصائيات التي يطبعها لا تتضمن النفقات العامة التي تمت إضافتها بواسطة Heapy نفسها. يمكن أن تكون هذه النفقات العامة ذات أهمية كبيرة (لقد رأيت عملية 100 ميجابايت RSS تنمو عشرات أخرى أو نحو ذلك ، انظر http://www.pkgcore.org/trac/pkgcore/doc/dev-notes/heapy.rst ).
لكن في حالتك ، أظن أن المشكلة هي أنك تستخدم بعض مكتبة C التي تتسرب أو تستخدم الذاكرة بطريقة لا يتتبعها Heapy. يدرك Heapy الذاكرة المستخدمة مباشرةً بواسطة كائنات Python ، ولكن إذا كانت هذه الكائنات تلتزم كائنات C التي يتم تخصيصها بشكل منفصل ، فهذا لا يدرك عادة تلك الذاكرة على الإطلاق. قد تكون قادرًا على إضافة دعم Heapy إلى روابطك (ولكن إذا لم تتحكم في الارتباطات التي تستخدمها ، فمن الواضح أنها متاعب ، وحتى إذا كنت تتحكم في الارتباطات ، فقد لا تتمكن من القيام بذلك اعتمادًا على ما تقوم بلفه ).
إذا كانت هناك تسرب على مستوى C ، ستفقد Heapy أيضًا تتبع تلك الذاكرة (سترتفع حجم RSS ولكن حجم Heapy المبلغ عنه سيبقى كما هو). من المحتمل أن يكون Valgrind أفضل رهان لتتبعها ، تمامًا كما هو الحال في تطبيقات C الأخرى.
أخيرًا: غالبًا ما يتسبب تجزئة الذاكرة في استخدام ذاكرتك (كما هو موضح في الأعلى) ، ولكن ليس للانخفاض (كثيرًا). هذا عادة لا يمثل مشكلة كبيرة مع الشياطين ، لأن العملية ستعيد استخدام هذه الذاكرة ، فهي لم تعود إلى نظام التشغيل ، وبالتالي فإن القيم في الأعلى لا تتراجع. إذا ارتفع استخدام الذاكرة (كما يراه أعلى) بشكل أو بآخر خطيًا مع عدد المستخدمين (الاتصالات) ، فإنه لا يعود إلى الأسفل ، ولكنه أيضًا لا يستمر في النمو إلى الأبد حتى تصل إلى الحد الأقصى الجديد من المستخدمين ، فمن المحتمل أن يكون التجزئة لإلقاء اللوم.
هذه ليست إجابة كاملة ، ولكن من فتحتك ، أقترح أيضًا تشغيل GC.Collect يدويًا () قبل البحث مع PS أو Top. سيعرض Guppy الكومة المخصصة ، لكنه لا يفعل أي شيء للكائنات المجانية بشكل استباقي لم تعد مخصصة.