gdb pyrasite guppy meliae

查看 进程的线程数量

  1. ps -o nlwp pid
  2. top -p
  3. pstree -p pid

pyrasite查看内存

  1. pyrasite-memory-viewer pid

pyrasite 进入进程交互

  1. pyrasite-shell pid

guppy

  1. from guppy import hpy
  2. hp = hpy()
  3. h = hp.heap()
  4. print h
  5. h[0].bytype
  6. #,查看这个占内存最大的list中的数据类型。
  7. from guppy import hpy;hxx = hpy();byrcs = hxx.heap().byrcs; byrcs[0].byid

gc

  1. import gc
  2. gc.garbage
  3. #手动释放
  4. gc.collect()

根据对象的id/address动态获取对象

  1. import ctypes
  2. obj = ctypes.cast(<addr_or_id>, ctypes.py_object).value

dump出所有对象地址

  1. from meliae import loader,scanner
  2. path = '/tmp/pyrasite.json'
  3. meliae.scanner.dump_all_objects(path)
  4. om = loader.load(path)
  5. #计算各Objects的引用关系
  6. om.compute_parents()
  7. #去掉各对象Instance的_dict_属性
  8. om.collapse_instance_dicts()
  9. #分析内存占用情况
  10. Index : 行索引号
  11. Count : 该类型的对象总数
  12. %(Count) : 该类型的对象总数 所有类型的对象总数 的百分比
  13. Size : 该类型的对象总字节数
  14. %(Size) : 该类型的对象总字节数 所有类型的对象总字节数 的百分比
  15. Cum : 累积行索引后的%(Size)
  16. Max : 该类型的对象中,最大者的字节数
  17. Kind : 类型
  18. print om.summarize()
  19. #得到所有的POP3ClientProtocol对象
  20. p = om.get_all('POP3ClientProtocol')
  21. #查看第一个对象
  22. p[0]
  23. #说明该对象的地址为2803894924,占用了1.7K内存,引用了51个对象,它被1个对象所引用
  24. #可以查看该对象的所有引用
  25. p[0].c
  26. #查看谁引用了这个对象
  27. p[0].p

gdb

  1. #接入gdb
  2. gdb python pid
  3. #查看线程
  4. info threads
  5. #coredump 如果要进行比较长时间的跟踪, 最好将python程序的进程信息全部coredump出来, 之后对core文件进行分析, 避免影响正在运行的程序.
  6. generate-core-file

进程内查看内存

  1. pyrasite-shell 11122
  2. >>> import psutil, os
  3. >>> psutil.Process(os.getpid()).memory_info().rss
  4. 29095232

查看python实际内存占用,非sys.getsizeof

  1. import sys
  2. import inspect
  3. def get_size(obj, seen=None):
  4. """Recursively finds size of objects in bytes"""
  5. size = sys.getsizeof(obj)
  6. if seen is None:
  7. seen = set()
  8. obj_id = id(obj)
  9. if obj_id in seen:
  10. return 0
  11. # Important mark as seen *before* entering recursion to gracefully handle
  12. # self-referential objects
  13. seen.add(obj_id)
  14. if hasattr(obj, '__dict__'):
  15. size += get_size(obj.__dict__, seen)
  16. if hasattr(obj, '__class__'):
  17. if hasattr(obj.__class__, '__mro__'):
  18. for cls in obj.__class__.__mro__:
  19. if '__dict__' in cls.__dict__:
  20. d = cls.__dict__['__dict__']
  21. if inspect.isgetsetdescriptor(d) or inspect.ismemberdescriptor(d):
  22. size += get_size(obj.__dict__, seen)
  23. break
  24. if isinstance(obj, dict):
  25. size += sum((get_size(v, seen) for v in obj.values()))
  26. size += sum((get_size(k, seen) for k in obj.keys()))
  27. elif hasattr(obj, '__iter__') and not isinstance(obj, (str, bytes, bytearray)):
  28. size += sum((get_size(i, seen) for i in obj))
  29. if hasattr(obj, '__slots__'): # can have __slots__ with __dict__
  30. size += sum(get_size(getattr(obj, s), seen) for s in obj.__slots__ if hasattr(obj, s))
  31. return size
  32. obj_list = []
  33. for x in gc.get_objects():
  34. try:size = get_size(x)
  35. except:size=0
  36. obj_list.append((type(x),size,id(x),str(x)[:10]) )
  37. obj_list = []
  38. for k,x in locals().items():
  39. try:size = get_size(x)
  40. except:size=0
  41. obj_list.append((type(x),size,id(x),str(x)[:10],k) )
  42. obj_list = []
  43. for k,x in globals().items():
  44. try:size = get_size(x)
  45. except:size=0
  46. obj_list.append((type(x),size,id(x),str(x)[:10],k) )
  47. import pandas as pd
  48. import numpy as np
  49. import sys
  50. pd.set_option('display.max_columns', 5)
  51. df = pd.DataFrame({'type':[x[0] for x in obj_list],
  52. 'size': [x[1] for x in obj_list],
  53. 'id': [x[2] for x in obj_list],
  54. 'str': [x[3] for x in obj_list],
  55. 'key': [x[4] for x in obj_list]
  56. })
  57. #类型大小排序
  58. df['size'].groupby(df['type']).sum().sort_values(ascending=False).head(10)
  59. #对象大小占用排序
  60. df.sort_values(by='size',ascending=False)
  61. sorted(obj_list,key=lambda x:x[1],reverse=True)

解决方案

  1. yum install autoconf automake gnome-common,libtool,gcc,c++
  2. wget https://github.com/gperftools/gperftools/archive/gperftools-2.6.1.tar.gz
  3. tar -zvxf gperftools-2.6.1.tar.gz
  4. cd gperftools-gperftools-2.6.1
  5. ./autogen.sh
  6. ./configure
  7. make
  8. make install
  9. echo '/usr/local/lib' > /etc/ld.so.conf.d/local.conf
  10. LD_PRELOAD="/usr/local/lib/libtcmalloc.so" python

查看执行时间

  1. python -m cProfile -o test1.out server.py
  2. python -c "import pstats; p=pstats.Stats('test1.out'); p.sort_stats('time').print_stats()" >b