python内存管理是通过引用计数执行的,如果指向某个对象的引用全部过期,那么受引用的对象就可以从内存中清除,从而给其他数据腾出空间。理论上讲,python开发不用担心程序如何分配和释放内存,因为python系统本身以及Cpython运行环境会自动处理这些问题。
但实际情况程序会因为没有及时释放不再需要引用的数据耗尽内存。下面通过一些方法来看下内存使用情况。
下面是被测试代码,这个代码可以创建对象,在gc中产生引用对象。
import osclass MyObject:def __init__(self):self.data = os.urandom(100)def get_data():values = []for _ in range(100):obj = MyObject()values.append(obj)return valuesdef run():deep_values = []for _ in range(100):deep_values.append(get_data())return
下面的代码用来输出当前gc引用对象的数量
import gc# 获取运行前gc引用对象数量
found_objects = gc.get_objects()
print('Before:', len(found_objects))# 导入待测试模块
import waste_memory# 运行待测试代码的函数
hold_reference = waste_memory.run()# 获取运行代码后gc引用对象数量
found_objects = gc.get_objects()
print('After: ', len(found_objects))
for obj in found_objects[:5]:print(repr(obj)[:100])print('...')
运行上面的代码,下面是gc引用的对象总数。
Before: 28834
After: 28923
上面只输出了gc的总数,对于分析内存分配情况没有太多的指导意义,tracemalloc模块能够追溯到分配它的位置,因此我们可以在之前模块前后对内存使用情况做个快照,分析两个快照之间的区别。
下面是被测试代码
import tracemalloctracemalloc.start(10) # Set stack depth
time1 = tracemalloc.take_snapshot() # Before snapshotimport waste_memoryx = waste_memory.run() # Usage to debug
time2 = tracemalloc.take_snapshot() # After snapshotstats = time2pare_to(time1, 'lineno') # Compare snapshots
for stat in stats[:3]:print(stat)
运行上面的代码,从结果中可以看出,每一条记录都有size与count指标,用来表示这行代码所分配的对象占用多少内存,以及对象的数量。通过对比就能发现占用内存较多的对象是由那几行代码分配的。
/waste_memory.py:11: size=5120 B (+5120 B), count=80 (+80), average=64 B
/waste_memory.py:14: size=4424 B (+4424 B), count=79 (+79), average=56 B
/waste_memory.py:9: size=1704 B (+1704 B), count=8 (+8), average=213 B
tracemalloc还可以打印栈的追踪信息,下面把程序中分配内存最多的那行代码所对应的栈追踪信息打印出来,看看程序是沿着哪条路径触发这行代码的。
import tracemalloctracemalloc.start(10)
time1 = tracemalloc.take_snapshot()import waste_memoryx = waste_memory.run()
time2 = tracemalloc.take_snapshot()stats = time2pare_to(time1, 'traceback')
top = stats[0]
print('Biggest offender is:')
# 打印栈信息
print('n'.aceback.format()))
运行上面的代码
Biggest offender is:File "/with_trace.py", line 14x = waste_memory.run()File "/waste_memory.py", line 23deep_values.append(get_data())File "/waste_memory.py", line 16obj = MyObject()File "/waste_memory.py", line 11self.data = os.urandom(100)
本文发布于:2024-02-03 03:43:04,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170690298448427.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |